home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-22 | 136.8 KB | 4,272 lines |
- // copyright 1993 Michael B. Johnson; some portions copyright 1994, MIT
- // see COPYRIGHT for reuse legalities
- //
-
- /* Copyright 1993 Michael B. Johnson
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any non-commercial
- * purpose and without fee is hereby granted, provided that the
- * above copyright notice appears in all copies. Michael B. Johnson
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * Permission to use, copy, modify or distribute this software
- * and its documentation for any commercial purpose must be
- * confirmed in writing with Michael B. Johnson. He can be
- * contacted at:
- * 20 Ames St. E15-023G
- * Cambridge, MA 02141
- * (617) 547 0563
- *
- */
-
-
- #import "WW3DCamera.h"
-
- #import "WWInterp.h" // this includes WWTCLWidgets.h
-
- #import "WW3DShape.h"
- #import "WW3DShader.h"
- #import "WW3DText.h"
- #import "RIBColor.h"
- #import "RIBTorus.h"
- #import "WW3DLight.h"
-
- #import "WW3DWell.h"
- #import "WWSceneClock.h" // has the sceneClock protocol - formalize this!
-
- #import <mach/cthreads.h>
-
- @implementation WW3DCamera
-
- + initialize { return [WW3DCamera setVersion:4], self; }
-
- static char errBuf[1024];
-
- /*
- ==========================================================================
- subext() -- Remove extension from fname only if it is there.
-
- ==========================================================================
- */
- static char
- *subext(fname, ext)
- register char *fname, *ext;
- {
- int fl, el;
-
- for ( fl = strlen(fname), el = strlen(ext);
- --el > -1 && --fl > -1 && fname[fl] == ext[el]; )
- ;
- if (el == -1)
- { fname[fl] = '\0';
- }
- return(fname);
- }
-
-
- /*
- ==========================================================================
- basename() -- deletes any prefix ending in `/' and the suffix.
-
- ==========================================================================
- */
- static char
- *basename(str, sfx, dest)
- char *str, *sfx, *dest;
- {
- char temp[1024];
- char *p, *p1;
- char *subext();
-
- p = p1 = temp;
- strcpy(p, str);
- while (*p)
- { if (*p++ == '/')
- { p1 = p;
- }
- }
- strcpy (dest, subext(p1, sfx));
- return(dest);
- }
-
-
- static int
- cmd_dumpRIBToFile(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "filename";
- int num_args = 2;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me dumpRIBToFile:argv[1]];
-
- return TCL_OK;
- }
-
- static int
- cmd_display(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me display];
-
- return TCL_OK;
- }
-
- static int
- cmd_backgroundColor(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "[{r g b}]";
- NXColor backgroundColor;
- int argc2;
- char **argv2;
- float red, green, blue;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if ((argc != 1) && (argc != 2) && (argc != 4))
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- if (argc == 1)
- { backgroundColor = [me backgroundColor];
- sprintf(interp->result, "{%f %f %f}",
- NXRedComponent(backgroundColor),
- NXGreenComponent(backgroundColor),
- NXBlueComponent(backgroundColor));
- return TCL_OK;
- }
- if (argc == 2)
- { Tcl_SplitList(interp, argv[1], &argc2, &argv2);
- if (argc2 != 3)
- { sprintf(errBuf, "USAGE: %s %s (colors should have 3 components)", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- if (argv2) { free(argv2); }
- return TCL_ERROR;
- }
- red = (float)atof(argv2[0]);
- green = (float)atof(argv2[1]);
- blue = (float)atof(argv2[2]);
- free(argv2);
- backgroundColor = NXConvertRGBAToColor(red, green, blue, 1.0);
- [me setBackgroundColor:backgroundColor];
- backgroundColor = [me backgroundColor];
- sprintf(interp->result, "{%f %f %f}",
- NXRedComponent(backgroundColor),
- NXGreenComponent(backgroundColor),
- NXBlueComponent(backgroundColor));
- return TCL_OK;
- }
- if (argc == 4)
- { red = (float)atof(argv[1]);
- green = (float)atof(argv[2]);
- blue = (float)atof(argv[3]);
- backgroundColor = NXConvertRGBAToColor(red, green, blue, 1.0);
- [me setBackgroundColor:backgroundColor];
- backgroundColor = [me backgroundColor];
- sprintf(interp->result, "{%f %f %f}",
- NXRedComponent(backgroundColor),
- NXGreenComponent(backgroundColor),
- NXBlueComponent(backgroundColor));
- return TCL_OK;
- }
- return TCL_ERROR;
- }
-
- static int
- cmd_fieldOfView(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "[fov]";
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if ((argc != 1) && (argc != 2))
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- if (argc == 1)
- { sprintf(interp->result, "%f", [me fieldOfView]);
- return TCL_OK;
- }
- if (argc == 2)
- { [me setFieldOfViewByAngle:(float)atof(argv[1])];
- sprintf(interp->result, "%f", [me fieldOfView]);
- return TCL_OK;
- }
- return TCL_ERROR;
- }
-
- static int
- cmd_setEyeAtTowardRoll(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "fromPoint toPoint aRollAngle";
- int num_args = 4, argc2;
- RtPoint fromPoint, toPoint;
- float aRollAngle;
- char **argv2;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- Tcl_SplitList(interp, argv[1], &argc2, &argv2); // fromPoint
- if (argc2 != 3)
- { sprintf(errBuf, "USAGE: %s %s (points should have 3 components)", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- if (argv2) { free(argv2); }
- return TCL_ERROR;
- }
- N3D_XComp(fromPoint) = (float)atof(argv2[0]);
- N3D_YComp(fromPoint) = (float)atof(argv2[1]);
- N3D_ZComp(fromPoint) = (float)atof(argv2[2]);
- free(argv2);
-
- Tcl_SplitList(interp, argv[2], &argc2, &argv2); // fromPoint
- if (argc2 != 3)
- { sprintf(errBuf, "USAGE: %s %s (points should have 3 components)", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- if (argv2) { free(argv2); }
- return TCL_ERROR;
- }
- N3D_XComp(toPoint) = (float)atof(argv2[0]);
- N3D_YComp(toPoint) = (float)atof(argv2[1]);
- N3D_ZComp(toPoint) = (float)atof(argv2[2]);
- free(argv2);
-
- aRollAngle = (float)atof(argv[3]);
-
- [me setEyeAt:fromPoint toward:toPoint roll:aRollAngle];
-
- return TCL_OK;
- }
-
- static int
- cmd_moveEyeBy(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "sDistance tDistance uDistance";
- int num_args = 4;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me moveEyeBy:(float)atof(argv[1]) :(float)atof(argv[2]) :(float)atof(argv[3])];
- //[[me delegate] cameraParametersWereUpdated:me];
- return TCL_OK;
- }
-
- static int
- cmd_getEyePoint(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
- RtPoint eyePoint, viewPoint;
- float aRollAngle;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me getEyeAt:&eyePoint toward:&viewPoint roll:&aRollAngle];
- sprintf(interp->result,
- "%f %f %f",
- N3D_XComp(eyePoint), N3D_YComp(eyePoint), N3D_ZComp(eyePoint));
- return TCL_OK;
- }
-
- static int
- cmd_getViewPoint(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
- RtPoint eyePoint, viewPoint;
- float aRollAngle;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me getEyeAt:&eyePoint toward:&viewPoint roll:&aRollAngle];
- sprintf(interp->result,
- "%f %f %f",
- N3D_XComp(viewPoint), N3D_YComp(viewPoint), N3D_ZComp(viewPoint));
- return TCL_OK;
- }
-
- static int
- cmd_getRollAngle(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
- RtPoint eyePoint, viewPoint;
- float aRollAngle;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me getEyeAt:&eyePoint toward:&viewPoint roll:&aRollAngle];
- sprintf(interp->result, "%f", aRollAngle);
- return TCL_OK;
- }
-
- static int
- cmd_getEyeAtTowardRoll(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
- RtPoint eyePoint, viewPoint;
- float aRollAngle;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me getEyeAt:&eyePoint toward:&viewPoint roll:&aRollAngle];
- sprintf(interp->result,
- "{%f %f %f} {%f %f %f} %f",
- N3D_XComp(eyePoint), N3D_YComp(eyePoint), N3D_ZComp(eyePoint),
- N3D_XComp(viewPoint), N3D_YComp(viewPoint), N3D_ZComp(viewPoint),
- aRollAngle);
- return TCL_OK;
- }
-
- static int
- cmd_setSurfaceTypeForAll(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "PointCloud|WireFrame|ShadedWireFrame|FacetedSolids|SmoothSolids";
- int num_args = 2;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- if (!strcmp(argv[1], "PointCloud"))
- { [me setSurfaceTypeForAll:N3D_PointCloud chooseHider:YES];
- //[[me delegate] cameraParametersWereUpdated:me];
- return TCL_OK;
- }
- if (!strcmp(argv[1], "WireFrame"))
- { [me setSurfaceTypeForAll:N3D_WireFrame chooseHider:YES];
- //[[me delegate] cameraParametersWereUpdated:me];
- return TCL_OK;
- }
- if (!strcmp(argv[1], "ShadedWireFrame"))
- { [me setSurfaceTypeForAll:N3D_ShadedWireFrame chooseHider:YES];
- //[[me delegate] cameraParametersWereUpdated:me];
- return TCL_OK;
- }
- if (!strcmp(argv[1], "FacetedSolids"))
- { [me setSurfaceTypeForAll:N3D_FacetedSolids chooseHider:YES];
- //[[me delegate] cameraParametersWereUpdated:me];
- return TCL_OK;
- }
- if (!strcmp(argv[1], "SmoothSolids"))
- { [me setSurfaceTypeForAll:N3D_SmoothSolids chooseHider:YES];
- //[[me delegate] cameraParametersWereUpdated:me];
- return TCL_OK;
- }
-
- sprintf(errBuf, "ERROR: unknown surface type <%s>\nUSAGE: %s %s", argv[1], argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_removeDefaultLights(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me removeDefaultLights];
- //[[me delegate] cameraParametersWereUpdated:me];
-
- return TCL_OK;
- }
-
- static int
- cmd_restoreDefaultLights(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- [me restoreDefaultLights];
- //[[me delegate] cameraParametersWereUpdated:me];
-
- return TCL_OK;
- }
-
- static int
- cmd_lightList(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1, i;
- id theLightList;
- N3DLight *light;
- N3DLightType lightType;
- char aBuf[MAXPATHLEN];
- RtPoint from, to;
- RtFloat coneAngle, coneDelta, beamDistribution;
- NXColor color;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- theLightList = [me lightList];
-
- Tcl_AppendResult(interp, "{", (char *)NULL);
- for (i = 0; i < [theLightList count]; i++)
- { light = [theLightList objectAt:i];
- Tcl_AppendResult(interp, "{", (char *)NULL);
-
- sprintf(aBuf, "name %s", [light shapeName]);
- Tcl_AppendElement(interp, aBuf);
-
- lightType = [light type];
- switch (lightType)
- { case N3D_AmbientLight: Tcl_AppendElement(interp, "type ambient");
- break;
- case N3D_PointLight: Tcl_AppendElement(interp, "type point");
- break;
- case N3D_DistantLight: Tcl_AppendElement(interp, "type distant");
- break;
- case N3D_SpotLight: Tcl_AppendElement(interp, "type spot");
- break;
- default: Tcl_AppendElement(interp, "type unknown");
- break;
- }
-
- [light getFrom:&from to:&to];
- sprintf(aBuf, "from %f %f %f", from[0], from[1], from[2]);
- Tcl_AppendElement(interp, aBuf);
- sprintf(aBuf, "to %f %f %f", to[0], to[1], to[2]);
- Tcl_AppendElement(interp, aBuf);
-
- sprintf(aBuf, "intensity %f", [light intensity]);
- Tcl_AppendElement(interp, aBuf);
-
- [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- sprintf(aBuf, "coneAngle %f", coneAngle);
- Tcl_AppendElement(interp, aBuf);
- sprintf(aBuf, "coneDelta %f", coneDelta);
- Tcl_AppendElement(interp, aBuf);
- sprintf(aBuf, "beamDistribution %f", beamDistribution);
- Tcl_AppendElement(interp, aBuf);
-
- color = [light color];
- sprintf(aBuf, "color %f %f %f",
- NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color));
- Tcl_AppendElement(interp, aBuf);
-
- sprintf(aBuf, "isGlobal %d", (int)[light isGlobal]);
- Tcl_AppendElement(interp, aBuf);
-
- Tcl_AppendResult(interp, "}", (char *)NULL);
- }
- Tcl_AppendResult(interp, "}", (char *)NULL);
- return TCL_OK;
- }
-
-
- static int
- cmd_otherLightList(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1, i;
- id theLightList;
- N3DLight *light;
- N3DLightType lightType;
- char aBuf[MAXPATHLEN];
- RtPoint from, to;
- RtFloat coneAngle, coneDelta, beamDistribution;
- NXColor color;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- theLightList = [me otherLightList];
-
- Tcl_AppendResult(interp, "{", (char *)NULL);
- for (i = 0; i < [theLightList count]; i++)
- { light = [theLightList objectAt:i];
- Tcl_AppendResult(interp, "{", (char *)NULL);
-
- sprintf(aBuf, "name %s", [light shapeName]);
- Tcl_AppendElement(interp, aBuf);
-
- lightType = [light type];
- switch (lightType)
- { case N3D_AmbientLight: Tcl_AppendElement(interp, "type ambient");
- break;
- case N3D_PointLight: Tcl_AppendElement(interp, "type point");
- break;
- case N3D_DistantLight: Tcl_AppendElement(interp, "type distant");
- break;
- case N3D_SpotLight: Tcl_AppendElement(interp, "type spot");
- break;
- default: Tcl_AppendElement(interp, "type unknown");
- break;
- }
-
- [light getFrom:&from to:&to];
- sprintf(aBuf, "from %f %f %f", from[0], from[1], from[2]);
- Tcl_AppendElement(interp, aBuf);
- sprintf(aBuf, "to %f %f %f", to[0], to[1], to[2]);
- Tcl_AppendElement(interp, aBuf);
-
- sprintf(aBuf, "intensity %f", [light intensity]);
- Tcl_AppendElement(interp, aBuf);
-
- [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- sprintf(aBuf, "coneAngle %f", coneAngle);
- Tcl_AppendElement(interp, aBuf);
- sprintf(aBuf, "coneDelta %f", coneDelta);
- Tcl_AppendElement(interp, aBuf);
- sprintf(aBuf, "beamDistribution %f", beamDistribution);
- Tcl_AppendElement(interp, aBuf);
-
- color = [light color];
- sprintf(aBuf, "color %f %f %f",
- NXRedComponent(color), NXGreenComponent(color), NXBlueComponent(color));
- Tcl_AppendElement(interp, aBuf);
-
- sprintf(aBuf, "isGlobal %d", (int)[light isGlobal]);
- Tcl_AppendElement(interp, aBuf);
-
- Tcl_AppendResult(interp, "}", (char *)NULL);
- }
- Tcl_AppendResult(interp, "}", (char *)NULL);
- return TCL_OK;
- }
-
-
- static int
- cmd_addAmbientLight(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name intensity [pathToParent]";
- int num_args = 3;
- WW3DLight *light;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if ((argc != num_args) && (argc != (num_args+1)))
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- light = [[[WW3DLight alloc] init] makeAmbientWithIntensity:(RtFloat)atof(argv[2])];
- [light setShapeName:argv[1]];
- if (argc == (num_args + 1)) // local, visible light
- { if (![me addLocalLight:light usingPath:argv[num_args]])
- { sprintf(errBuf, "unable to add local ambient light %s as a child of shape %s", argv[1], argv[num_args]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- }
- else // regular global light
- { [me addLight:light];
- }
- return TCL_OK;
- }
-
-
- static int
- cmd_addPointLight(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name fromX fromY fromZ intensity [pathToParent]";
- int num_args = 6;
- RtPoint from;
- WW3DLight *light;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if ((argc != num_args) && (argc != (num_args+1)))
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- from[0] = (RtFloat)atof(argv[2]);
- from[1] = (RtFloat)atof(argv[3]);
- from[2] = (RtFloat)atof(argv[4]);
- light = [[[WW3DLight alloc] init] makePointFrom:from intensity:(RtFloat)atof(argv[4])];
- [light setShapeName:argv[1]];
- if (argc == (num_args + 1)) // local, visible light
- { if (![me addLocalLight:light usingPath:argv[num_args]])
- { sprintf(errBuf, "unable to add local point light %s as a child of shape %s", argv[1], argv[num_args]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- }
- else // regular global light
- { [me addLight:light];
- }
-
- return TCL_OK;
- }
-
-
- static int
- cmd_addDistantLight(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name fromX fromY fromZ toX toY toZ intensity [pathToParent]";
- int num_args = 9;
- RtPoint from, to;
- WW3DLight *light;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if ((argc != num_args) && (argc != (num_args+1)))
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- from[0] = (RtFloat)atof(argv[2]);
- from[1] = (RtFloat)atof(argv[3]);
- from[2] = (RtFloat)atof(argv[4]);
- to[0] = (RtFloat)atof(argv[5]);
- to[1] = (RtFloat)atof(argv[6]);
- to[2] = (RtFloat)atof(argv[7]);
- light = [[[WW3DLight alloc] init] makeDistantFrom:from to:to intensity:(RtFloat)atof(argv[8])];
- [light setShapeName:argv[1]];
- if (argc == (num_args + 1)) // local, visible light
- { if (![me addLocalLight:light usingPath:argv[num_args]])
- { sprintf(errBuf, "unable to add local distant light %s as a child of shape %s", argv[1], argv[num_args]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- }
- else // regular global light
- { [me addLight:light];
- }
-
- return TCL_OK;
- }
-
-
- static int
- cmd_addSpotLight(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name fromX fromY fromZ toX toY toZ coneAngle coneDelta beamDistribution intensity [pathToParent]";
- int num_args = 12;
- RtPoint from, to;
- WW3DLight *light;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if ((argc != num_args) && (argc != (num_args+1)))
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- from[0] = (RtFloat)atof(argv[2]);
- from[1] = (RtFloat)atof(argv[3]);
- from[2] = (RtFloat)atof(argv[4]);
- to[0] = (RtFloat)atof(argv[5]);
- to[1] = (RtFloat)atof(argv[6]);
- to[2] = (RtFloat)atof(argv[7]);
- light = [[[WW3DLight alloc] init] makeSpotFrom:from to:to
- coneAngle:(RtFloat)atof(argv[8])
- coneDelta:(RtFloat)atof(argv[9])
- beamDistribution:(RtFloat)atof(argv[10])
- intensity:(RtFloat)atof(argv[11])];
- [light setShapeName:argv[1]];
- if (argc == (num_args + 1)) // local, visible light
- { if (![me addLocalLight:light usingPath:argv[num_args]])
- { sprintf(errBuf, "unable to add local point light %s as a child of shape %s", argv[1], argv[num_args]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- }
- else // regular global light
- { [me addLight:light];
- }
-
- return TCL_OK;
- }
-
-
- static int
- cmd_setLightIntensity(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name intensity";
- int num_args = 3, i;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setIntensity:(RtFloat)atof(argv[2])];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setIntensity:(RtFloat)atof(argv[2])];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set intensity...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightType(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name type";
- int num_args = 3, i;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
- N3DLightType lightType = N3D_AmbientLight;
- BOOL validLightType = NO;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- if (!strcmp(argv[2], "ambient"))
- { lightType = N3D_AmbientLight;
- validLightType = YES;
- }
- if (!strcmp(argv[2], "point"))
- { lightType = N3D_PointLight;
- validLightType = YES;
- }
- if (!strcmp(argv[2], "distant"))
- { lightType = N3D_DistantLight;
- validLightType = YES;
- }
- if (!strcmp(argv[2], "spot"))
- { lightType = N3D_SpotLight;
- validLightType = YES;
- }
- if (!validLightType)
- { sprintf(errBuf, "%s is not a valid light type (ambient|point|distant|spot)", argv[2]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setType:lightType];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setType:lightType];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set type...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightFrom(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name fromX fromY fromZ";
- int num_args = 5, i;
- RtPoint from;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- from[0] = (RtFloat)atof(argv[2]);
- from[1] = (RtFloat)atof(argv[3]);
- from[2] = (RtFloat)atof(argv[4]);
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setFrom:from];
- return TCL_OK;
- }
- }
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setFrom:from];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set from point...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightTo(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name toX toY toZ";
- int num_args = 5, i;
- RtPoint from, to;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getFrom:&from to:&to];
- to[0] = (RtFloat)atof(argv[2]);
- to[1] = (RtFloat)atof(argv[3]);
- to[2] = (RtFloat)atof(argv[4]);
- [light setFrom:from to:to];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getFrom:&from to:&to];
- to[0] = (RtFloat)atof(argv[2]);
- to[1] = (RtFloat)atof(argv[3]);
- to[2] = (RtFloat)atof(argv[4]);
- [light setFrom:from to:to];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set to point...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightColor(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name r g b";
- int num_args = 5, i;
- NXColor color;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- color = NXConvertRGBToColor((float)atof(argv[2]), (float)atof(argv[3]), (float)atof(argv[4]));
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setColor:color];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light setColor:color];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set color...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightConeAngleConeDeltaBeamDistribution(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name coneAngle coneDelta beamDistribution";
- int num_args = 5, i;
- RtFloat coneAngle, coneDelta, beamDistribution;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { coneAngle = (RtFloat)atof(argv[2]);
- coneDelta = (RtFloat)atof(argv[3]);
- beamDistribution = (RtFloat)atof(argv[4]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { coneAngle = (RtFloat)atof(argv[2]);
- coneDelta = (RtFloat)atof(argv[3]);
- beamDistribution = (RtFloat)atof(argv[4]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set coneAngle, coneDelta, beamDistribution...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightConeAngle(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name coneAngle";
- int num_args = 3, i;
- RtFloat coneAngle, coneDelta, beamDistribution;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- coneAngle = (RtFloat)atof(argv[2]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- coneAngle = (RtFloat)atof(argv[2]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set coneAngle...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightConeDelta(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name coneDelta";
- int num_args = 3, i;
- RtFloat coneAngle, coneDelta, beamDistribution;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- coneDelta = (RtFloat)atof(argv[2]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- coneDelta = (RtFloat)atof(argv[2]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set coneDelta...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_setLightBeamDistribution(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "name beamDistribution";
- int num_args = 3, i;
- RtFloat coneAngle, coneDelta, beamDistribution;
- WW3DLight *light;
- id lightList = [me lightList];
- id otherLightList = [me otherLightList];
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- beamDistribution = (RtFloat)atof(argv[2]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- for (i = 0; i < [otherLightList count]; i++)
- { light = [otherLightList objectAt:i];
- if (!strcmp(argv[1], [light shapeName]))
- { [light getConeAngle:&coneAngle coneDelta:&coneDelta beamDistribution:&beamDistribution];
- beamDistribution = (RtFloat)atof(argv[2]);
- [light setConeAngle:coneAngle coneDelta:coneDelta beamDistribution:beamDistribution];
- return TCL_OK;
- }
- }
-
- sprintf(errBuf, "no light named %s - unable to set beamDistribution...", argv[1]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
-
- static int
- cmd_removeLight(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- int i;
-
-
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- for (i = 1; i < argc; i++)
- { if (![me removeLightNamed:argv[i]])
- { sprintf(errBuf, "no light named %s - no further light removal done...", argv[i]);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- }
-
- return TCL_OK;
- }
-
-
- static int
- cmd_rotateAroundY(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "u", **argv2, *str;
- int num_args = 2, argc2;
- RtPoint originalView;
- RtPoint originalEye, newEye;
- double u, radius, radiusSq;
- RtFloat originalRollAngle;
-
-
- //sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- //[[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
-
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- // u varies from 0 to 1, and describes a perfect circle around the original look at point.
- // we want to stay at the same Y point, and move around in a circle, such that the radius
- // of the circle we're describing stays constant.
- // we just want to set a new eye point and then reset the viewpoint to be the same as it had been.
- u = (float)atof(argv[1]);
-
- // need to grab "startCam(eyePoint)", which is a list
- str = [[me tclInterp] getVar2:"startCam" :"eyePoint"];
- if (!str)
- { sprintf(errBuf, "startCam(viewPoint) is no defined - unable to interpolate");
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- Tcl_SplitList(interp, str, &argc2, &argv2);
- if (argc2 != 3)
- { sprintf(errBuf, "startCam(eyePoint) is supposed to have 3 elements, not %d", argc2);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- N3D_XComp(originalEye) = (float)atof(argv2[0]);
- N3D_YComp(originalEye) = (float)atof(argv2[1]);
- N3D_ZComp(originalEye) = (float)atof(argv2[2]);
-
- // need to grab "startCam(viewPoint)", which is a list
- str = [[me tclInterp] getVar2:"startCam" :"viewPoint"];
- if (!str)
- { sprintf(errBuf, "startCam(viewPoint) is no defined - unable to interpolate");
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- Tcl_SplitList(interp, str, &argc2, &argv2);
- if (argc2 != 3)
- { sprintf(errBuf, "startCam(viewPoint) is supposed to have 3 elements, not %d", argc2);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
- N3D_XComp(originalView) = (float)atof(argv2[0]);
- N3D_YComp(originalView) = (float)atof(argv2[1]);
- N3D_ZComp(originalView) = (float)atof(argv2[2]);
-
- radiusSq = ((N3D_XComp(originalEye) - N3D_XComp(originalView)) * (N3D_XComp(originalEye) - N3D_XComp(originalView)))
- + ((N3D_ZComp(originalEye) - N3D_ZComp(originalView)) * (N3D_ZComp(originalEye) - N3D_ZComp(originalView)));
- radius = sqrt(radiusSq);
- NXLogError("radius == %f\n", radius);
- N3D_XComp(newEye) = N3D_XComp(originalView) + ((N3D_XComp(originalEye) - N3D_XComp(originalView)) * cos(2 * PI * u));
- N3D_YComp(newEye) = N3D_YComp(originalEye);
- N3D_ZComp(newEye) = N3D_ZComp(originalView) + ((N3D_ZComp(originalEye) - N3D_ZComp(originalView)) * sin(2 * PI * u));
-
- // need to grab "startCam(rollAngle)"
- str = [[me tclInterp] getVar2:"startCam" :"rollAngle"];
- originalRollAngle = (RtFloat)atof(str);
-
- [me setEyeAt:newEye toward:originalView roll:originalRollAngle];
-
- return TCL_OK;
- }
-
- static int
- cmd_noop(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- sprintf(errBuf, "WW3DCamera's interp evaluating %s...", argv[0]);
- [[me statusText] setStringValue:errBuf]; [[me statusText] display]; NXPing();
- return TCL_OK;
- }
-
- #if 0
- static int
- cmd_(me, interp, argc, argv)
- WW3DCamera *me;
- Tcl_Interp *interp;
- int argc;
- char **argv;
- {
- char *my_args = "";
- int num_args = 1;
-
-
- if (argc != num_args)
- { sprintf(errBuf, "USAGE: %s %s", argv[0], my_args);
- Tcl_AppendResult(interp, errBuf, (char *)NULL);
- return TCL_ERROR;
- }
-
- return TCL_OK;
- }
- #endif
-
- - initInterp
- {
- [tclInterp addCommand:"dumpRIBToFile" :cmd_dumpRIBToFile :self];
- [tclInterp addCommand:"display" :cmd_display :self];
- [tclInterp addCommand:"backgroundColor" :cmd_backgroundColor :self];
- [tclInterp addCommand:"fieldOfView" :cmd_fieldOfView :self];
- [tclInterp addCommand:"setEyeAt:toward:roll:" :cmd_setEyeAtTowardRoll :self];
- [tclInterp addCommand:"setEyeAtTowardRoll" :cmd_setEyeAtTowardRoll :self];
- [tclInterp addCommand:"moveEyeBy:::" :cmd_moveEyeBy :self];
- [tclInterp addCommand:"moveEyeBy" :cmd_moveEyeBy :self];
- [tclInterp addCommand:"setSurfaceTypeForAll" :cmd_setSurfaceTypeForAll :self];
- [tclInterp addCommand:"getEyePoint" :cmd_getEyePoint :self];
- [tclInterp addCommand:"getViewPoint" :cmd_getViewPoint :self];
- [tclInterp addCommand:"getRollAngle" :cmd_getRollAngle :self];
- [tclInterp addCommand:"getEyeAt:toward:roll:" :cmd_getEyeAtTowardRoll :self];
- [tclInterp addCommand:"getEyeAtTowardRoll" :cmd_getEyeAtTowardRoll :self];
- [tclInterp addCommand:"removeDefaultLights" :cmd_removeDefaultLights :self];
- [tclInterp addCommand:"restoreDefaultLights" :cmd_restoreDefaultLights :self];
- [tclInterp addCommand:"lightList" :cmd_lightList :self];
- [tclInterp addCommand:"otherLightList" :cmd_otherLightList :self];
- [tclInterp addCommand:"localLightList" :cmd_otherLightList :self];
- [tclInterp addCommand:"addAmbientLight" :cmd_addAmbientLight :self];
- [tclInterp addCommand:"addPointLight" :cmd_addPointLight :self];
- [tclInterp addCommand:"addDistantLight" :cmd_addDistantLight :self];
- [tclInterp addCommand:"addSpotLight" :cmd_addSpotLight :self];
- [tclInterp addCommand:"setLightIntensity" :cmd_setLightIntensity :self];
- [tclInterp addCommand:"setLightType" :cmd_setLightType :self];
- [tclInterp addCommand:"setLightFrom" :cmd_setLightFrom :self];
- [tclInterp addCommand:"setLightTo" :cmd_setLightTo :self];
- [tclInterp addCommand:"setLightColor" :cmd_setLightColor :self];
- [tclInterp addCommand:"setLightConeAngleConeDeltaBeamDistribution" :cmd_setLightConeAngleConeDeltaBeamDistribution :self];
- [tclInterp addCommand:"setLightConeAngle" :cmd_setLightConeAngle :self];
- [tclInterp addCommand:"setLightConeDelta" :cmd_setLightConeDelta :self];
- [tclInterp addCommand:"setLightBeamDistribution" :cmd_setLightBeamDistribution :self];
- [tclInterp addCommand:"removeLight" :cmd_removeLight :self];
-
- [tclInterp addCommand:"rotateAroundY" :cmd_rotateAroundY :self];
-
- [tclInterp addCommand:"askModel" :cmd_noop :self];
- [tclInterp addCommand:"noop" :cmd_noop :self];
-
- return self;
- }
-
- - setupDefaultLights
- {
- RtPoint lFromP = {0.5,0.5,-0.75};
- RtPoint lToP = {0, 0, 0};
-
- // ambient light
- ambientLight=[[WW3DLight alloc] init];
- [ambientLight setShapeName:"ambientLight"];
- [ambientLight makeAmbientWithIntensity:0.3];
- [self addLight:ambientLight];
-
- // distant light
- rightLight=[[WW3DLight alloc] init];
- [rightLight setShapeName:"rightDistantLight"];
- [rightLight makeDistantFrom:lFromP to:lToP intensity:0.7];
- [self addLight:rightLight];
-
- // point light
- //N3D_XComp( lFromP ) = -0.5;
- //N3D_YComp( lFromP ) = -0.5;
- //leftLight=[[WW3DLight alloc] init];
- //[leftLight setShapeName:"leftPointLight"];
- //[leftLight makePointFrom:lFromP intensity:0.7];
- //[self addLight:leftLight];
-
- defaultLightsInUse = YES;
-
- return self;
- }
-
- - restoreDefaultLights
- {
- if (!defaultLightsInUse)
- { [self addLight:ambientLight];
- [self addLight:rightLight];
- //[self addLight:leftLight];
- defaultLightsInUse = YES;
- }
- return self;
- }
-
- - removeDefaultLights
- {
- if (defaultLightsInUse)
- { [self removeLight:ambientLight];
- [self removeLight:rightLight];
- [self removeLight:leftLight];
- defaultLightsInUse = NO;
- }
- return self;
- }
-
-
- - removeLightNamed:(const char *)lightName
- {
- int i;
- id light;
-
-
- for (i = 0; i < [lightList count]; i++)
- { light = [lightList objectAt:i];
- if (!strcmp(lightName, [light shapeName]))
- { [self removeLight:light];
- return self;
- }
- }
- return nil;
- }
-
-
- - setFieldOfViewByAngle:(float)viewAngle
- {
- char buf[128];
-
-
- [super setFieldOfViewByAngle:viewAngle];
- sprintf(buf, "%f", viewAngle);
- [tclInterp setVar2:"cam" :"fieldOfView" toValue:buf];
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- char *ReadOnlyWriteProc(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- return "this is a read-only variable";
- }
-
-
- char *WriteProcForInterpolationProc(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- // when a new interpolation proc is defined, there are several things we want to do.
- // first of all, we want to make sure that it's valid:
- // - a valid interpolation proc only has one argument: u
-
- // the other thing we might want to do is update the inspector panel (if we have one) about the contents of this guy...
-
- return NULL;
- }
-
-
- // someone is writing a new value for the cam(fieldOfView) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
-
- // really should constrain fov to be from <0 && <180
- char *WriteProcForFieldOfViewByAngle(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float fieldOfView = 45.;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- sscanf(varString, "%f", &fieldOfView);
- [[(WWTCLVarTrace *)clientData datum] setFieldOfViewByAngle:fieldOfView];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(fieldOfView) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForFieldOfViewByAngle(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float fieldOfView;
-
-
- fieldOfView = [[(WWTCLVarTrace *)clientData datum] fieldOfView];
- sprintf(buf, "%f", fieldOfView);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - setEyeAt:(RtPoint)fromPoint toward:(RtPoint)toPoint roll:(float)aRollAngle;
- {
- char buf[384];
-
-
- [super setEyeAt:fromPoint toward:toPoint roll:aRollAngle];
-
- sprintf(buf, "%f %f %f", N3D_XComp(fromPoint), N3D_YComp(fromPoint), N3D_ZComp(fromPoint));
- [tclInterp setVar2:"cam" :"eyePoint" toValue:buf];
- sprintf(buf, "%f %f %f", N3D_XComp(toPoint), N3D_YComp(toPoint), N3D_ZComp(toPoint));
- [tclInterp setVar2:"cam" :"viewPoint" toValue:buf];
- sprintf(buf, "%f", aRollAngle);
- [tclInterp setVar2:"cam" :"rollAngle" toValue:buf];
-
- //[delegate cameraParametersWereUpdated:self];
- return self;
- }
-
- // someone is writing a new value for the cam(eyePoint) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForEyePoint(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString, **argv;
- int argc;
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- // get current values
- [[(WWTCLVarTrace *)clientData datum] getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- Tcl_SplitList(interp, varString, &argc, &argv); // fromPoint
- if (argc != 3)
- { NXLogError("cam(eyePoint) should be a tcl list with 3 components, not <%s>\n", varString);
- if (argv) { free(argv); }
- return NULL;
- }
- N3D_XComp(anEyePoint) = (float)atof(argv[0]);
- N3D_YComp(anEyePoint) = (float)atof(argv[1]);
- N3D_ZComp(anEyePoint) = (float)atof(argv[2]);
- free(argv);
-
- [[(WWTCLVarTrace *)clientData datum] setEyeAt:anEyePoint toward:aViewPoint roll:aRollAngle];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam() parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForEyePoint(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[384];
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- // get current values
- [[(WWTCLVarTrace *)clientData datum] getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
-
- sprintf(buf, "%f %f %f", N3D_XComp(anEyePoint), N3D_YComp(anEyePoint), N3D_ZComp(anEyePoint));
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- // someone is writing a new value for the cam(viewPoint) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForViewPoint(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString, **argv;
- int argc;
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- // get current values
- [[(WWTCLVarTrace *)clientData datum] getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- Tcl_SplitList(interp, varString, &argc, &argv); // viewPoint
- if (argc != 3)
- { NXLogError("cam(viewPoint) should be a tcl list with 3 components, not <%s>\n", varString);
- if (argv) { free(argv); }
- return NULL;
- }
- N3D_XComp(aViewPoint) = (float)atof(argv[0]);
- N3D_YComp(aViewPoint) = (float)atof(argv[1]);
- N3D_ZComp(aViewPoint) = (float)atof(argv[2]);
- free(argv);
-
- [[(WWTCLVarTrace *)clientData datum] setEyeAt:anEyePoint toward:aViewPoint roll:aRollAngle];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(viewPoint) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForViewPoint(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[384];
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- // get current values
- [[(WWTCLVarTrace *)clientData datum] getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
-
- sprintf(buf, "%f %f %f", N3D_XComp(aViewPoint), N3D_YComp(aViewPoint), N3D_ZComp(aViewPoint));
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- // someone is writing a new value for the cam(rollAngle) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForRollAngle(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- // get current values
- [[(WWTCLVarTrace *)clientData datum] getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- aRollAngle = (float)atof(varString);
-
- [[(WWTCLVarTrace *)clientData datum] setEyeAt:anEyePoint toward:aViewPoint roll:aRollAngle];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(rollAngle) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForRollAngle(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[384];
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- // get current values
- [[(WWTCLVarTrace *)clientData datum] getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
-
- sprintf(buf, "%f", aRollAngle);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
-
- - (RtFloat)fStop { return fStop; }
-
- - setFStop:(float)newFStop
- {
- char buf[128];
-
-
- fStop = newFStop;
- sprintf(buf, "%f", fStop);
- [tclInterp setVar2:"cam" :"fStop" toValue:buf];
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(fStop) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForFStop(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float fStop = 1.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- sscanf(varString, "%f", &fStop);
- [[(WWTCLVarTrace *)clientData datum] setFStop:fStop];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(fStop) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForFStop(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float fStop;
-
-
- fStop = [[(WWTCLVarTrace *)clientData datum] fStop];
- sprintf(buf, "%f", fStop);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (RtFloat)focalLength { return focalLength; }
-
- - setFocalLength:(float)newFocalLength
- {
- char buf[128];
-
-
- focalLength = newFocalLength;
- sprintf(buf, "%f", focalLength);
- [tclInterp setVar2:"cam" :"focalLength" toValue:buf];
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(fStop) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForFocalLength(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float focalLength = 1.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- sscanf(varString, "%f", &focalLength);
- [[(WWTCLVarTrace *)clientData datum] setFocalLength:focalLength];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(fStop) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForFocalLength(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float focalLength;
-
-
- focalLength = [[(WWTCLVarTrace *)clientData datum] focalLength];
- sprintf(buf, "%f", focalLength);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (RtFloat)focalDistance { return focalDistance; }
-
- - setFocalDistance:(float)newFocalDistance
- {
- char buf[128];
-
-
- focalDistance = newFocalDistance;
- sprintf(buf, "%f", focalDistance);
- [tclInterp setVar2:"cam" :"focalDistance" toValue:buf];
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(focalDistance) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForFocalDistance(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float focalDistance = 1.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- sscanf(varString, "%f", &focalDistance);
- [[(WWTCLVarTrace *)clientData datum] setFocalDistance:focalDistance];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(focalDistance) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForFocalDistance(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float focalDistance;
-
-
- focalDistance = [[(WWTCLVarTrace *)clientData datum] focalDistance];
- sprintf(buf, "%f", focalDistance);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - setFrameNumber:(int)aFrameNumber
- {
- char buf[128];
-
-
- if ((aFrameNumber <= [self endFrame]) && ([self frameNumber] != aFrameNumber)) //it's valid and it's new
- { // if it's actually a new frame, we need to flip the "evaluateInterpProc"
- // flag, so that the next time we render, we run the camera interpolation routine...
- evaluateInterpProc = YES;
- }
-
- // we assume that the [super setFrameNumber:] clamps to endFrameNumber
- [super setFrameNumber:aFrameNumber];
-
- // by setting the frame number, we need to make sure that all the
- // appropriate other parts of the camera have been updated. What
- // automatically follows along? Well, the shutterOpenTime needs to get
- // updated, at least...
- [self setShutterOpenTime:(shotStartTime + (frameNumber * frameTimeIncrement))];
-
- sprintf(buf, "%d", frameNumber);
- [tclInterp setVar2:"cam" :"frameNumber" toValue:buf];
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- - resetFrameNumber
- {
- [self setFrameNumber:0];
- return self;
- }
-
- // someone is writing a new value for the cam(frameNumber) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForFrameNumber(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- int frameNumber = 1;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
-
- // frameNumber has to be an integer
-
-
- sscanf(varString, "%d", &frameNumber);
- [[(WWTCLVarTrace *)clientData datum] setFrameNumber:frameNumber];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(frameNumber) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForFrameNumber(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- int frameNumber;
-
-
- frameNumber = [[(WWTCLVarTrace *)clientData datum] frameNumber];
- sprintf(buf, "%d", frameNumber);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- // whenever the frame number or the frameTimeIncrement gets changed,
- // the open and close time need to be recalculated
-
- - (RtFloat)shutterOpenTime { return shutterOpenTime; }
-
- - setShutterOpenTime:(RtFloat)newShutterOpenTime
- {
- char buf[128];
-
-
- shutterOpenTime = newShutterOpenTime;
- sprintf(buf, "%f", shutterOpenTime);
- [tclInterp setVar2:"cam" :"shutterOpenTime" toValue:buf];
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(shutterOpenTime) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForShutterOpenTime(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- RtFloat shutterOpenTime = 0.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- sscanf(varString, "%f", &shutterOpenTime);
- [[(WWTCLVarTrace *)clientData datum] setShutterOpenTime:shutterOpenTime];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(shutterOpenTime) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForShutterOpenTime(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- RtFloat shutterOpenTime;
-
-
- shutterOpenTime = [[(WWTCLVarTrace *)clientData datum] shutterOpenTime];
- sprintf(buf, "%f", shutterOpenTime);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (RtFloat)shutterCloseTime { return (shutterOpenTime + (exposureLength * exposureLengthFactor)); }
-
- // someone is writing a new value for the cam(shutterCloseTime) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForShutterCloseTime(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- return "cam(shutterCloseTime) is read-only";
- }
-
-
- // someone is reading a value for the cam(shutterCloseTime) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForShutterCloseTime(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- RtFloat shutterCloseTime;
-
-
- shutterCloseTime = [[(WWTCLVarTrace *)clientData datum] shutterCloseTime];
- sprintf(buf, "%f", shutterCloseTime);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (float)frameTimeIncrement { return frameTimeIncrement; }
-
- - (float)exposureLength { return exposureLength; }
-
- - setExposureLength:(float)newExposureLength
- {
- char buf[128];
-
- // need to make sure that the new exposure length is consistent with the rest of the camera
- // what does this mean?
- // the length of the exposure cannot be longer than the interval between frames, i.e.
- // exposureLength <= (frameTimeIncrement == 1./framesPerSecond)
- //
- //NXLogError("newExposureLength == %f\n", newExposureLength);
-
- if (newExposureLength < 0.0)
- { NXLogError("exposureLength must be a positive number, not %f\n", newExposureLength);
- return nil;
- }
-
- // actually, we only want to do this if we're shooting. Anyway, at
- // the start of shooting a shot (i.e. an ordered sequence), we should
- // sanity check then - this might be perfectly reasonable for a still
- // frame...
- if (shooting)
- { if (newExposureLength > [self frameTimeIncrement])
- { exposureLength = [self frameTimeIncrement];
- }
- else
- { exposureLength = newExposureLength;
- }
- }
- else // don't do a clip; it could be whatever positive value they want...
- { exposureLength = newExposureLength;
- }
- sprintf(buf, "%f", exposureLength);
- [tclInterp setVar2:"cam" :"exposureLength" toValue:buf];
- //[delegate cameraParametersWereUpdated:self];
- justResetExposureLength = YES;
-
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(exposureLength) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForExposureLength(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- RtFloat exposureLength = 0.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
- sscanf(varString, "%f", &exposureLength);
- [[(WWTCLVarTrace *)clientData datum] setExposureLength:exposureLength];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(exposureLength) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForExposureLength(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- RtFloat exposureLength;
-
-
- exposureLength = [[(WWTCLVarTrace *)clientData datum] exposureLength];
- sprintf(buf, "%f", exposureLength);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (float)framesPerSecond { return framesPerSecond; }
-
- - setFramesPerSecond:(float)newFramesPerSecond
- {
- char buf[128];
- RtFloat maxExposureLength;
- int newEndFrame;
-
-
- // okay, the frames/second is being changed.
- // what do we need to update?
- // we want the duration of the shot (in seconds) to stay the same,
- // so we need to:
- // - make sure that the exposureLength is still valid; if not, clamp it
- // - reset the startFrame to 0 and the endFrame to whatever is appropriate
-
- framesPerSecond = newFramesPerSecond;
- sprintf(buf, "%f", newFramesPerSecond);
- [tclInterp setVar2:"cam" :"FramesPerSecond" toValue:buf];
-
- frameTimeIncrement = (1.0/framesPerSecond);
- maxExposureLength = frameTimeIncrement;
-
- // if, by changing the frame rate, we've invalidated the current
- // setting for how long the shutter stays open for each frame, we need to
- // reset it to a valid value. If it's still valid, leave it be (i.e. if
- // it was a strobe camera, it will stay that way).
- // uh, no. There are two normal cases: keep the exposureLength at 0.0, for a strobe,
- // or keep the exposureLength == frameTimeIncrement. So... if they want a special
- // setting, they'll need to reset it after setting a new fps.
- // uh, no I changed my mind again. If they want a *strobe*, they have to reset it explicitly
- // this is what I want in most cases (i.e. I want motion blur)
- [self setExposureLength:maxExposureLength];
-
- newEndFrame = (framesPerSecond * [self shotLength]); // actually should do the right thing at the half frame mark...
- [super setStartFrame:0 endFrame:newEndFrame incrementFramesBy:[self frameIncrement]];
-
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(framesPerSecond) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForFramesPerSecond(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float framesPerSecond = 17.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
-
- // framesPerSecond has to be a float
- sscanf(varString, "%f", &framesPerSecond);
- [[(WWTCLVarTrace *)clientData datum] setFramesPerSecond:framesPerSecond];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(framesPerSecond) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForFramesPerSecond(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float framesPerSecond;
-
-
- framesPerSecond = [[(WWTCLVarTrace *)clientData datum] framesPerSecond];
- sprintf(buf, "%f", framesPerSecond);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (float)shotLength { return shotLength; }
-
- - setShotLength:(float)newShotLength
- {
- char buf[128];
- int newEndFrame;
-
-
- // okay, the frames/second is being changed.
- // what do we need to update?
- // - reset the startFrame to 0 and the endFrame to whatever is appropriate
-
- shotLength = newShotLength;
- sprintf(buf, "%f", newShotLength);
- [tclInterp setVar2:"cam" :"shotLength" toValue:buf];
-
- newEndFrame = (shotLength * [self framesPerSecond]) - 1; // actually should the right thing at the half frame mark...
- [super setStartFrame:0 endFrame:newEndFrame incrementFramesBy:[self frameIncrement]];
-
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(shotLength) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForShotLength(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float shotLength = 17.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
-
- // ShotLength has to be a float
- sscanf(varString, "%f", &shotLength);
- [[(WWTCLVarTrace *)clientData datum] setShotLength:shotLength];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(ShotLength) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForShotLength(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float shotLength;
-
-
- shotLength = [[(WWTCLVarTrace *)clientData datum] shotLength];
- sprintf(buf, "%f", shotLength);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (float)shotStartTime { return shotStartTime; }
-
- - setShotStartTime:(float)newShotStartTime
- {
- char buf[128];
-
-
- shotStartTime = newShotStartTime;
- sprintf(buf, "%f", newShotStartTime);
- [tclInterp setVar2:"cam" :"shotStartTime" toValue:buf];
-
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(shotStartTime) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForShotStartTime(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float shotStartTime = 0.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
-
- // ShotStartTime has to be a float
- sscanf(varString, "%f", &shotStartTime);
- [[(WWTCLVarTrace *)clientData datum] setShotStartTime:shotStartTime];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(shotStartTime) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForShotStartTime(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float shotStartTime;
-
-
- shotStartTime = [[(WWTCLVarTrace *)clientData datum] shotStartTime];
- sprintf(buf, "%f", shotStartTime);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (float)exposureLengthFactor { return exposureLengthFactor; }
-
- - setExposureLengthFactor:(float)newExposureLengthFactor
- {
- char buf[128];
-
-
- exposureLengthFactor = newExposureLengthFactor;
- // bound it inclusively between 0 and 1
- if (exposureLengthFactor < 0.0)
- { exposureLengthFactor = 0.0;
- }
- if (exposureLengthFactor > 1.0)
- { exposureLengthFactor = 1.0;
- }
- sprintf(buf, "%f", newExposureLengthFactor);
- [tclInterp setVar2:"cam" :"exposureLengthFactor" toValue:buf];
-
- //[delegate cameraParametersWereUpdated:self];
-
- return self;
- }
-
-
- // someone is writing a new value for the cam(exposureLengthFactor) parameter, so we need
- // to update the WW3DCamera to reflect that new value...
- char *WriteProcForExposureLengthFactor(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char *varString;
- float exposureLengthFactor = 0.0;
-
-
- varString = [[(WWTCLVarTrace *)clientData tclInterp] getVar2:name1 :name2];
-
- // exposureLengthFactor has to be a float
- sscanf(varString, "%f", &exposureLengthFactor);
- [[(WWTCLVarTrace *)clientData datum] setExposureLengthFactor:exposureLengthFactor];
-
- return NULL;
- }
-
-
- // someone is reading a value for the cam(exposureLengthFactor) parameter, so we need
- // to " read-through" the WW3DCamera to reflect the current value...
- char *ReadProcForExposureLengthFactor(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags)
- {
- char buf[128];
- float exposureLengthFactor;
-
-
- exposureLengthFactor = [[(WWTCLVarTrace *)clientData datum] exposureLengthFactor];
- sprintf(buf, "%f", exposureLengthFactor);
- [[(WWTCLVarTrace *)clientData tclInterp] setVar2:name1 :name2 toValue:buf];
-
- return NULL;
- }
-
- - (BOOL)shooting { return shooting; }
-
- - setShooting:(BOOL)newShooting
- {
- if (shooting && !newShooting)
- { justFinishedShooting = YES;
- }
- shooting = newShooting;
-
- return self;
- }
-
- - takeShooting:sender
- {
- [self setShooting:(BOOL)[sender intValue]];
- return self;
- }
-
- // in this routine, the tcl interp is assumed to have the correct values, and so the camera has to conform to it...
- // cam(fieldOfView) : fieldOfView : float -> float
- // cam(eyePoint) : eyePoint : RtPoint -> {x y z}
- // cam(viewPoint) : viewPoint : RtPoint -> {x y z}
- // cam(rollAngle) : rollAngle : float -> float
- // cam(fStop) : fStop : float -> float
- // cam(focalLength) : focalLength : float -> float
- // cam(focalDistance) : focalDistance : float -> float
- // cam(frameNumber) : frameNumber : int -> int
-
- // NOT DONE YET!
- // cam(pixelAspectRatio) : pixelAspectRatio : float -> float
- // cam(projectionType) : projectionType : N3DProjectionType -> string
- // cam(backgroundColor) : backgroundColor : NXColor -> {r g b}
- // cam(doesDrawBackgroundColor) : doesDrawBackgroundColor : BOOL -> int
- // cam(nearPlane) : nearPlane : float -> float
- // cam(farPlane) : farPlane : float -> float
-
- // need to talk about interdependencies of these variables...
- // send mail to Dan at Pixar and ask, especially about fStop, focalLength, and focalDistance...
-
- - setupTraces
- {
- char *valAsString, *varName;
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- valAsString = (char *)NXZoneCalloc([self zone], 256, sizeof(char));
- varName = (char *)NXZoneCalloc([self zone], 256, sizeof(char));
-
- // need to pull out my current camera parameters and send them as
- // "set cam(paramName) paramValue" to my interp here...
- // and then we need to set up read and write traces so that any set calls
- // on any cam() variable will be in synch with this instance...
-
-
- // you may be asking yourself here: "why is wave, that bozo, copying
- // the strings that correspond to the variables names into a tmp
- // variable? Is he really that wasteful, just because he has bigger
- // and more expensive equipment than I do? Is he intentionally wasting
- // my precious time?" Well, sports fans, no. The problem is that
- // the current (7.3) implementation of tcl still uses a performance
- // hack that gets bit by compilers being smart. The short answer is
- // if you hand tcl a const char* that the compiler has squirreled away
- // somewhere in read-only space, you will dump core, because tcl,
- // while doing a comparison on array elements, attempts to stick a '\0'
- // where the '(' is so it can do a fast hash table lookup. It's very
- // good about taking the '\0' out once its done, but unfortunately,
- // you'll never get the chance... This is reasonably well documented
- // in the tcl doc, and given the efficiency, I can't really complain,
- // but it *is* a bug (whether in C, the compiler, or tcl, you make the call).
- // Anyway, to get around it, you either use the setVar2 version, or
- // you make sure that the string you hand into setVar is writable.
- // gak...
-
- //
- strcpy(varName, "cam(fieldOfView)");
- sprintf(valAsString, "%f", [self fieldOfView]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForFieldOfViewByAngle usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForFieldOfViewByAngle usingData:(ClientData)self];
-
- //
- [self getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
-
- strcpy(varName, "cam(eyePoint)");
- sprintf(valAsString, "%f %f %f", N3D_XComp(anEyePoint), N3D_YComp(anEyePoint), N3D_ZComp(anEyePoint));
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForEyePoint usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForEyePoint usingData:(ClientData)self];
-
- strcpy(varName, "cam(viewPoint)");
- sprintf(valAsString, "%f %f %f", N3D_XComp(aViewPoint), N3D_YComp(aViewPoint), N3D_ZComp(aViewPoint));
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForViewPoint usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForViewPoint usingData:(ClientData)self];
-
- strcpy(varName, "cam(rollAngle)");
- sprintf(valAsString, "%f", aRollAngle); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForRollAngle usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForRollAngle usingData:(ClientData)self];
-
- //
- strcpy(varName, "cam(fStop)");
- sprintf(valAsString, "%f", [self fStop]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForFStop usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForFStop usingData:(ClientData)self];
- //
- strcpy(varName, "cam(focalLength)");
- sprintf(valAsString, "%f", [self focalLength]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForFocalLength usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForFocalLength usingData:(ClientData)self];
- //
- strcpy(varName, "cam(focalDistance)");
- sprintf(valAsString, "%f", [self focalDistance]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForFocalDistance usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForFocalDistance usingData:(ClientData)self];
- //
- strcpy(varName, "cam(frameNumber)");
- sprintf(valAsString, "%d", [self frameNumber]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForFrameNumber usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForFrameNumber usingData:(ClientData)self];
- //
- strcpy(varName, "cam(shotLength)");
- sprintf(valAsString, "%f", [self shotLength]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForShotLength usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForShotLength usingData:(ClientData)self];
- //
- strcpy(varName, "cam(shotStartTime)");
- sprintf(valAsString, "%f", [self shotStartTime]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForShotStartTime usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForShotStartTime usingData:(ClientData)self];
- //
- strcpy(varName, "cam(framesPerSecond)");
- sprintf(valAsString, "%f", [self framesPerSecond]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForFramesPerSecond usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForFramesPerSecond usingData:(ClientData)self];
- //
- strcpy(varName, "cam(exposureLengthFactor)");
- sprintf(valAsString, "%f", [self exposureLengthFactor]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForExposureLengthFactor usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForExposureLengthFactor usingData:(ClientData)self];
- //
- strcpy(varName, "cam(shutterOpenTime)");
- sprintf(valAsString, "%f", [self shutterOpenTime]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForShutterOpenTime usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForShutterOpenTime usingData:(ClientData)self];
- //
- strcpy(varName, "cam(shutterCloseTime)");
- sprintf(valAsString, "%f", [self shutterCloseTime]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForShutterCloseTime usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForShutterCloseTime usingData:(ClientData)self];
- //
- strcpy(varName, "cam(exposureLength)");
- sprintf(valAsString, "%f", [self exposureLength]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForExposureLength usingData:(ClientData)self];
- [tclInterp traceReadsOn:varName andCall:(Tcl_VarTraceProc *)ReadProcForExposureLength usingData:(ClientData)self];
- //
- //
- strcpy(varName, "cam(interpolationProc)");
- // need to set up a default interpolation proc...
- sprintf(valAsString, "noop");
- [tclInterp setVar:varName toValue:valAsString];
- [tclInterp traceWritesOn:varName andCall:(Tcl_VarTraceProc *)WriteProcForInterpolationProc usingData:(ClientData)self];
-
- // continue for all variables...
-
-
- inSynchWithTclInterp = YES;
- NXZoneFree([self zone], valAsString);
- NXZoneFree([self zone], varName);
-
-
- return self;
- }
-
-
- - initFrame:(const NXRect *)r
- {
- RtPoint fromP = {0,0,-5.0}, toP = {0,0,0};
- id aShape;
-
-
- [super initFrame:r];
-
- // speed stuff up and help workaround HP 3.2 bug (32 bit w/qrman crashes WS)
- [self setOpaque:YES];
-
- tclInterp = [[WWInterp alloc] init];
-
- [self initInterp];
-
- renderStyle = N3D_SmoothSolids;
- movingRenderStyle = N3D_WireFrame;
-
- scaleUpFactor = 1.05;
- scaleDownFactor = 0.95;
- translateXFactor = 0.01;
- translateYFactor = 0.01;
- translateZFactor = 0.05;
- epsilon = 4.0;
- selectionWidthEpsilon = 8.0;
- selectionHeightEpsilon = 8.0;
- shadingRate = 4.0;
- renderAtMediumRate = 1;
- renderAtHighRate = 2;
- renderCheckTimeSlice = 3.0;
- showSelectedShape = YES;
- drawOriginForSelectedShape = NO;
-
- // setup 3D camera stuff
- [self setEyeAt:fromP toward:toP roll:0.0];
-
- [self setupDefaultLights];
- otherLightList = [[List alloc] init];
-
- // setup some initial global rendering state
- [self setSurfaceTypeForAll:renderStyle chooseHider:YES];
- lowRezTesselationVector[0] = lowRezTesselationVector[1] = 4.0;
- tesselationVector[0] = tesselationVector[1] = 16.0;
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, tesselationVector, RI_NULL);
-
- // stick in a reasonable shader
- theShader=[[WW3DShader alloc] init];
- [theShader setUseColor:YES];
- [theShader setColor:ribColor];
- [(N3DShader *)theShader setShader:"plastic"];
-
- // stick in a reasonable reference shape
- aShape = [[WW3DShape alloc] init];
- [aShape setShapeName:NXCopyStringBuffer("defaultTorus")];
- [aShape setShapeName:NXCopyStringBuffer("WW3DWell")];
- [aShape appendRIBCommand:[[RIBColor alloc] init]];
- //[aShape appendRIBCommand:[[RIBTorus alloc] init]];
-
- // To show off the RIBCommand archiving bug, uncomment the next
- // command, recompile, load up the WW3DPalette in IB (running IB in gdb),
- // and drag the well off the palette...
-
- [aShape appendRIBCommand:[[WW3DText alloc] initWithCharPath:"WW3DWell"
- usingFont:[Font newFont:"Helvetica"
- size:36]
- myShape:aShape justification:NX_CENTERED]];
-
- [aShape calculateBoundingBoxStartingAt:0.0 endingAt:0.0];
-
- [aShape setShader_:theShader];
- [[self setWorldShape:aShape] free]; // free the default world shape
- currentShape = nil;
- [self setCurrentShape:[self worldShape]]; // set current shape to be top
-
- [self setSurfaceTypeForAll:N3D_SmoothSolids chooseHider:YES];
-
- theRotator = [[N3DRotator alloc] initWithCamera:self];
- [theRotator setRotationAxis:N3D_AllAxes];
-
- [self setPreTransformMatrix:(RtFloat (*)[4])N3DIdentityMatrix];
- statusBufSize = 256;
- statusBuf = (char *)NXZoneCalloc([self zone], statusBufSize, sizeof(char));
-
- fStop = RI_INFINITY; // pinhole camera
- focalLength = 50;
- focalDistance = abs((N3D_ZComp(fromP) - N3D_ZComp(toP)));
-
- shutterOpenTime = 0.0;
- framesPerSecond = 15.0;
- frameTimeIncrement = 1.0/framesPerSecond; // start off with 15 fps
- savedExposureLength = exposureLength = frameTimeIncrement; // start off with a motion blurred still camera
- // start off with a film-like motion picture camera
- exposureLengthFactor = .5;
-
- // shot stuff
- shotStartTime = 0.0; // begin at the beginning...
- shotLength = 3.0; // let's start off with a 3 second shot
- frameNumber = 0;
- startFrame = 0;
- endFrame = shotLength * framesPerSecond;
-
- [self setShooting:NO];
- justFinishedShooting = NO;
- justResetExposureLength = NO;
-
- [self setupTraces];
-
- return self;
- }
-
- // the receptor gets sent this message when the object is dragged into
- // the File window, and when it is unarchived from the nib file.
- - awake
- {
- [super awake];
-
- // everything else has just been unarchived...
-
- [self initInterp];
- theRotator = [[N3DRotator alloc] initWithCamera:self];
- [theRotator setRotationAxis:N3D_AllAxes];
-
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, tesselationVector, RI_NULL);
-
- currentShape = nil;
- [self setCurrentShape:[self worldShape]]; // set current shape to be top
-
- statusBufSize = 256;
- statusBuf = (char *)NXZoneCalloc([self zone], statusBufSize, sizeof(char));
-
- frameTimeIncrement = 1.0/framesPerSecond;
- savedExposureLength = exposureLength;
- justFinishedShooting = NO;
- justResetExposureLength = NO;
-
- [self setupTraces];
-
- return self;
- }
-
- - free
-
- {
- if (statusBuf) { NXZoneFree([self zone], statusBuf); }
- [self removeAnimateTE];
- [self removeRenderTE];
-
- [super free];
-
- // make sure you free the tcl interp after the rootShape, because
- // EveCommands that get free'd will want to untrace their corresponding
- // tcl variables, and we don't want them sending messages to an already
- // free'd tclInterp
-
- [tclInterp free];
-
- self = nil;
- return self;
- }
-
-
- - synchToSceneClock:aSceneClock
- {
- float sceneTime = [aSceneClock timestamp];
-
-
- // the idea here is to advance to the first frame that shows the scene's time.
- [self setFrameNumber:(int)(sceneTime * framesPerSecond)];
- [self display];
- return self;
- }
-
-
- - dumpCameraStateTo:(const char *)camName
- {
- char *valAsString, *varName;
- RtPoint anEyePoint, aViewPoint;
- RtFloat aRollAngle;
-
-
- valAsString = (char *)NXZoneCalloc([self zone], 256, sizeof(char));
- varName = (char *)NXZoneCalloc([self zone], 256, sizeof(char));
-
- // need to pull out my current camera parameters and send them as
- // "set camName(paramName) paramValue" to my interp here...
- // and then we need to set up write traces so that any set calls fail
-
- //
- sprintf(varName, "%s(fieldOfView)", camName);
- sprintf(valAsString, "%f", [self fieldOfView]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- [self getEyeAt:&anEyePoint toward:&aViewPoint roll:&aRollAngle];
-
- sprintf(varName, "%s(eyePoint)", camName);
- sprintf(valAsString, "%f %f %f", N3D_XComp(anEyePoint), N3D_YComp(anEyePoint), N3D_ZComp(anEyePoint));
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
-
- sprintf(varName, "%s(viewPoint)", camName);
- sprintf(valAsString, "%f %f %f", N3D_XComp(aViewPoint), N3D_YComp(aViewPoint), N3D_ZComp(aViewPoint));
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
-
- sprintf(varName, "%s(rollAngle)", camName);
- sprintf(valAsString, "%f", aRollAngle); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(fStop)", camName);
- sprintf(valAsString, "%f", [self fStop]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(focalLength)", camName);
- sprintf(valAsString, "%f", [self focalLength]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(focalDistance)", camName);
- sprintf(valAsString, "%f", [self focalDistance]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(frameNumber)", camName);
- sprintf(valAsString, "%d", [self frameNumber]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(shutterOpenTime)", camName);
- sprintf(valAsString, "%f", [self shutterOpenTime]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(shutterCloseTime)", camName);
- sprintf(valAsString, "%f", [self shutterCloseTime]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(frameTimeIncrement)", camName);
- sprintf(valAsString, "%f", [self frameTimeIncrement]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
- sprintf(varName, "%s(exposureLength)", camName);
- sprintf(valAsString, "%f", [self exposureLength]); // turn the value into its tcl equivalent
- [tclInterp setVar:varName toReadOnlyValue:valAsString];
- //
-
- NXZoneFree([self zone], valAsString);
- NXZoneFree([self zone], varName);
-
- return self;
- }
-
-
- - evaluateCameraInterpolationRoutineWith:(float)u
- {
- char cmd[80];
-
-
- sprintf(cmd, "eval $cam(interpolationProc) %f", u);
- //NXLogError("WW3DCamera's interp evaluating camera interpolation routine with %f for frame number %d here...\n",
- // u, [self frameNumber]);
- [tclInterp globalEval:cmd];
- return self;
- }
-
-
- - worldBegin:(RtToken)context
- {
- RtInt jitterFlag = 1;
- float u;
- static RtInt v31 = 301;
- int theFrameNumber;
-
-
- if (dumpingToRIB)
- { RiOption(RI_ARCHIVE, "outputversion", &v31, RI_NULL);
- NXLogError("boy, I'm wicked compatible...\n");
- }
- RiImager("clamptoalpha", RI_NULL);
-
- // Run camera interpolation procedure here. We do it here (as opposed
- // to doing it in drawSelf:), because at this point, all the camera
- // parameters are as fixed as they're gonna get for this frame.
-
- // when a new frame number is set with setFrameNumber:, it sets the
- // BOOL evaluateInterpProc. We only want to run this proc once per
- // frame, but we also don't want to do it until this point. So...
- // at this point, if the flag is set, we evaluate the proc with
- // the current value of u.
- // note that if the currentFrame == startFrame, and the flag is set,
- // we need to do some initial work to set up the state. We need to
- // fill out the global tcl array startCam(), which is to have the state
- // of the current camera in read-only variables...
-
- if (shooting)
- { theFrameNumber = [self frameNumber];
-
- if (theFrameNumber == 0) // sanity check!
- { savedExposureLength = exposureLength;
- [self setExposureLength:([self frameTimeIncrement] * exposureLengthFactor)];
- }
- if (evaluateInterpProc)
- { if (theFrameNumber == 0)
- { // initialize startCam() array with my current state
- [tclInterp unsetVar:"startCam"];
- [self dumpCameraStateTo:"startCam"];
- u = 0;
- }
- else
- { // calculate u, where u is 0 at startFrame and 1 at endFrame
- // let's say startFrame is 0, endFrame is 100, and frameNumber is 25
- // we want u to be .25
- // note that we should not have to worry about div by zero here...
- u = (float)theFrameNumber/(float)([self endFrame] - 1);
- }
- [self evaluateCameraInterpolationRoutineWith:u];
- evaluateInterpProc = NO;
- }
- }
- else // if we're not shooting, we want the camera to be in synch with the scene clock and be a strobe camera...
- { // ask the sceneClock what time it is, and make ourselves a strobe camera
- if (justFinishedShooting) // when we come out of a shot, reset the exposureLength to what it was previously
- { [self setExposureLength:savedExposureLength]; // need to do it "correctly", so tcl is notified
- justFinishedShooting = NO;
- }
- [self setShutterOpenTime:[sceneClock timestamp]]; // need to do it "correctly", so tcl is notified
- }
-
- // If I want to support depth-of-field, need to call RiDepthOfField()
- RiDepthOfField(fStop, focalLength, focalDistance);
- // If I want to support motion blur, need to call RiShutter(), as well
- // as having RiMotionBegin/End blocks around primitives
- RiShutter(shutterOpenTime, (shutterOpenTime + (exposureLength * exposureLengthFactor)));
- if (exposureLength > 0.0) // is it a strobe or not?
- { // optimize for motion blur...
- // should make these variables, dude...
- RiPixelSamples(3.0, 3.0);
- // really should find out what the hider has been set to...
- RiHider("hidden", "jitter", &jitterFlag, RI_NULL);
- }
-
- // or whatever the heck is the right thang...
- if (renderCount == renderAtMediumRate)
- { RiShadingRate(50.0);
- }
- else
- { if (renderCount == renderAtHighRate)
- { RiShadingRate(5.0);
- }
- }
-
- [super worldBegin:context];
- return self;
- }
-
- - getTransformMatrix:(RtMatrix)aMatrix
- {
- N3D_CopyMatrix(transform, aMatrix);
- return self;
- }
-
- - takeStatusText:sender { statusText = sender; return self; }
-
- - delegate { return delegate; }
-
- ///////////////////////
- // 3D stuff
- ///////////////////////
- - setNoCurrentShape:sender { currentShape = nil; return self; }
-
- - currentShape { return currentShape; }
- - setCurrentShape:newCurrentShape
- {
- // should make sure newShape is a child of worldShape...
- [currentShape setSelected:NO andDrawOrigin:NO];
- currentShape = newCurrentShape;
- [currentShape setSelected:showSelectedShape andDrawOrigin:drawOriginForSelectedShape];
-
- // WAVE this is expensive; I should have a flag...
- //[self display];
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "currentShape is: %s", [currentShape shapeName]);
- [statusText setStringValue:statusBuf];
- }
-
- return self;
- }
-
- - (RtFloat)tesselation { return tesselationVector[0]; }
-
- - takeTesselation:sender
- {
- tesselationVector[0] = tesselationVector[1] = [sender floatValue];
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, tesselationVector, RI_NULL);
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "tesselation set to (%f %f)",
- tesselationVector[0], tesselationVector[1]);
- [statusText setStringValue:statusBuf];
- }
-
- [self display];
-
- return self;
- }
-
- - (RtFloat)lowRezTesselation { return lowRezTesselationVector[0]; }
-
- - takeLowRezTesselation:sender
- {
- lowRezTesselationVector[0] = lowRezTesselationVector[1] = [sender floatValue];
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "low rez tesselation set to (%f %f)",
- lowRezTesselationVector[0], lowRezTesselationVector[1]);
- [statusText setStringValue:statusBuf];
- }
- return self;
- }
-
- - (float)shadingRate { return shadingRate; }
- - takeShadingRate:sender
- {
- shadingRate = [sender floatValue];
- if (shadingRate < 0.25)
- { shadingRate = 0.25;
- }
- if (shadingRate > 100.0)
- { shadingRate = 100.0;
- }
- return self;
- }
-
- - takeAmbientLightState:sender
- {
- [ambientLight switchLight:[sender intValue]];
- return [self display];
- }
- - takeAmbientLightIntensity:sender
- {
- [ambientLight setIntensity:[sender floatValue]];
- return [self display];
- }
- - takeAmbientLightColor:sender
- {
- [ambientLight setColor:[sender color]];
- return [self display];
- }
- - takeLeftLightState:sender
- {
- [leftLight switchLight:[sender intValue]];
- return [self display];
- }
- - takeLeftLightIntensity:sender
- {
- [leftLight setIntensity:[sender floatValue]];
- return [self display];
- }
- - takeLeftLightColor:sender
- {
- [leftLight setColor:[sender color]];
- return [self display];
- }
- - takeRightLightState:sender
- {
- [rightLight switchLight:[sender intValue]];
- return [self display];
- }
- - takeRightLightIntensity:sender
- {
- [rightLight setIntensity:[sender floatValue]];
- return [self display];
- }
- - takeRightLightColor:sender
- {
- [rightLight setColor:[sender color]];
- return [self display];
- }
-
- - (BOOL)ambientLightState { return [ambientLight on]; }
- - (RtFloat)ambientLightIntensity { return [ambientLight intensity]; }
- - (NXColor)ambientLightColor { return [ambientLight color]; }
-
- - (BOOL)leftLightState { return [leftLight on]; }
- - (RtFloat)leftLightIntensity { return [leftLight intensity]; }
- - (NXColor)leftLightColor { return [leftLight color]; }
-
- - (BOOL)rightLightState { return [rightLight on]; }
- - (RtFloat)rightLightIntensity { return [ rightLight intensity]; }
- - (NXColor)rightLightColor { return [rightLight color]; }
-
- - saveImage:sender
- {
- static id savePanel=nil;
- NXStream *ts;
-
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- }
-
- [savePanel setRequiredFileType:"tiff"];
- if([savePanel runModal])
- { ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- [image writeTIFF:ts allRepresentations:NO usingCompression:NX_TIFF_COMPRESSION_LZW andFactor:1.0];
- NXSaveToFile(ts, [savePanel filename]);
- NXCloseMemory(ts,NX_FREEBUFFER);
- }
-
- return self;
- }
-
-
- - dumpRIB:sender
- {
- static id savePanel=nil;
- NXStream *ts;
- char filename[MAXPATHLEN+1];
-
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "dumping RIB...");
- [statusText setStringValue:statusBuf];
- }
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- [savePanel setRequiredFileType:"rib"];
- }
-
- if([savePanel runModal])
- { // returned w/pathname, open a stream and
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- // remove the .rib extension from the path returned by the SavePanel
- basename([savePanel filename], ".rib", filename);
-
- // feed to NXPrintf to put in the custom Display command
- NXPrintf(ts, "# This RIB file generated by Michael B. Johnson's WW3DKit software running under NeXTSTEP.\n");
- NXPrintf(ts, "# Contact him at wave@media.mit.edu or (617) 547-0563 for more information.\n#\n");
- NXPrintf(ts, "Display \"%s.tiff\" \"file\" \"rgba\"\n", filename);
- NXPrintf(ts, "ShadingRate %f\n", shadingRate);
-
- // then feed the rib code to the stream and
- [self copyRIBCode:ts];
- // save the stream to the file selected in the savepanel
- NXSaveToFile(ts, [savePanel filename]);
-
- // and close the stream (which also flushes it), also making sure
- // that the allocated memory is freed.
- NXCloseMemory(ts,NX_FREEBUFFER);
- }
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "done!");
- [statusText setStringValue:statusBuf];
- }
- return self;
- }
-
- - copyRIBCode:(NXStream *)ts
- {
- id retID, tmpText = statusText;
-
-
- sprintf(statusBuf, "disabling status display to avoid NeXT's copyRIBCode: bug...");
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- statusText = nil;
- retID = [super copyRIBCode:ts];
- statusText = tmpText;
- return retID;
- }
-
-
- - dumpShotToRIBFile:(const char *)longFilename
- {
- NXStream *ts;
- char filename[MAXPATHLEN+1];
- int oldFrameNumber, i, startI, endI, incI;
- static id savePanel=nil;
-
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "dumping complete shot to RIB file %s...", longFilename);
- [statusText setStringValue:statusBuf];
- }
-
- // make sure it's a RIB file (at least 1.rib)...
- if (longFilename && (strlen(longFilename) > 4) && (!strcmp(".rib", (const char *)(longFilename + strlen(longFilename) - 4))))
- { // returned w/pathname, open a stream and
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- // remove the .rib extension from the path returned by the SavePanel
- basename(longFilename, ".rib", filename);
-
- // feed to NXPrintf to put in the custom Display command
- NXPrintf(ts, "# This RIB file generated by Michael B. Johnson's WW3DKit software running under NeXTSTEP.\n");
- NXPrintf(ts, "# Contact him at wave@media.mit.edu or (617) 547-0563 for more information.\n#\n");
-
-
- // we need to loop over the whole shot, starting at the first frame, and incrementing correctly.
- // The 3DKit will take care of putting in frame numbers, but we need to manage the names of the
- // tiff files that will get saved out. The WWAnimatable and WWRenderable objects that this camera
- // is attached to will take care of figuring out what time it is when the camera takes their picture.
-
- NXPrintf(ts, "ShadingRate %f\n", shadingRate);
-
- oldFrameNumber = [self frameNumber];
- startI = [self startFrame];
- endI = [self endFrame];
- incI = [self frameIncrement];
-
- // due to a bug in NeXT's 3DKit, we want to make sure that
- // nothing gets written out to a view while we're in
- // "copyRIBCode:". Unfortunately, that's pretty hard... The most likely
- // culprit is a routine (like the current camera's interpolation routine)
- // writing out to the "statusText" outlet. Probably the best thing to do
- // then is to save the value of that outlet and set it to nil for the
- // duration of copyRIBCode:... actually, the better thing to do is
- // probably reimplement copyRIBCode:, where I unset the outlet, call
- // the super's version, and then set it back. Yea, let's try that...
-
- shooting = YES;
- [self setFrameNumber:(startI - 1)]; // just to flush state...
- for (i = startI; i < endI; i += incI)
- { [self setFrameNumber:i];
- NXPrintf(ts, "Display \"%s.%d.tiff\" \"file\" \"rgba\"\n", filename, i);
- [self copyRIBCode:ts];
- }
- NXSaveToFile(ts, [savePanel filename]);
- NXCloseMemory(ts,NX_FREEBUFFER);
-
- [self setFrameNumber:oldFrameNumber];
- shooting = NO;
- }
- else
- { sprintf(statusBuf, "<%s> is not a valid filename for a RIB file.\n", longFilename);
- [statusText setStringValue:statusBuf];
- return nil;
- }
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "done!");
- [statusText setStringValue:statusBuf];
- }
- return self;
- }
-
-
- - dumpShotToRIB:sender
- {
- static id savePanel=nil;
- NXStream *ts;
- char filename[MAXPATHLEN+1];
- int oldFrameNumber, i, startI, endI, incI;
-
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "dumping complete shot to RIB...");
- [statusText setStringValue:statusBuf];
- }
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- [savePanel setRequiredFileType:"rib"];
- }
-
- if([savePanel runModal])
- { // returned w/pathname, open a stream and
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- // remove the .rib extension from the path returned by the SavePanel
- basename([savePanel filename], ".rib", filename);
-
- // feed to NXPrintf to put in the custom Display command
- NXPrintf(ts, "# This RIB file generated by Michael B. Johnson's WW3DKit software running under NeXTSTEP.\n");
- NXPrintf(ts, "# Contact him at wave@media.mit.edu or (617) 547-0563 for more information.\n#\n");
-
-
- // we need to loop over the whole shot, starting at the first frame, and incrementing correctly.
- // The 3DKit will take care of putting in frame numbers, but we need to manage the names of the
- // tiff files that will get saved out. The WWAnimatable and WWRenderable objects that this camera
- // is attached to will take care of figuring out what time it is when the camera takes their picture.
-
- NXPrintf(ts, "ShadingRate %f\n", shadingRate);
-
- oldFrameNumber = [self frameNumber];
- startI = [self startFrame];
- endI = [self endFrame];
- incI = [self frameIncrement];
-
- // due to a bug in NeXT's 3DKit, we want to make sure that
- // nothing gets written out to a view while we're in
- // "copyRIBCode:". Unfortunately, that's pretty hard... The most likely
- // culprit is a routine (like the current camera's interpolation routine)
- // writing out to the "statusText" outlet. Probably the best thing to do
- // then is to save the value of that outlet and set it to nil for the
- // duration of copyRIBCode:... actually, the better thing to do is
- // probably reimplement copyRIBCode:, where I unset the outlet, call
- // the super's version, and then set it back. Yea, let's try that...
-
- shooting = YES;
- [self setFrameNumber:(startI - 1)]; // just to flush state...
- for (i = startI; i < endI; i += incI)
- { [self setFrameNumber:i];
- NXPrintf(ts, "Display \"%s.%d.tiff\" \"file\" \"rgba\"\n", filename, i);
- [self copyRIBCode:ts];
- }
- NXSaveToFile(ts, [savePanel filename]);
- NXCloseMemory(ts,NX_FREEBUFFER);
-
- [self setFrameNumber:oldFrameNumber];
- shooting = NO;
- }
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "done!");
- [statusText setStringValue:statusBuf];
- }
- return self;
- }
-
-
- - dumpShotToRIBAndEveScene:sender
- {
- static id savePanel=nil;
- NXStream *ts;
- char filename[MAXPATHLEN+1];
- int oldFrameNumber, i, startI, endI, incI;
- float theShotDuration;
-
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "dumping complete shot to RIB...");
- [statusText setStringValue:statusBuf];
- }
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- [savePanel setRequiredFileType:"rib"];
- }
-
- if([savePanel runModal])
- { // returned w/pathname, open a stream and
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- // remove the .rib extension from the path returned by the SavePanel
- basename([savePanel filename], ".rib", filename);
-
- // feed to NXPrintf to put in the custom Display command
- NXPrintf(ts, "# This RIB file generated by Michael B. Johnson's WW3DKit software running under NeXTSTEP.\n");
- NXPrintf(ts, "# Contact him at wave@media.mit.edu or (617) 547-0563 for more information.\n#\n");
-
-
- // we need to loop over the whole shot, starting at the first frame, and incrementing correctly.
- // The 3DKit will take care of putting in frame numbers, but we need to manage the names of the
- // tiff files that will get saved out. The WWAnimatable and WWRenderable objects that this camera
- // is attached to will take care of figuring out what time it is when the camera takes their picture.
-
- NXPrintf(ts, "ShadingRate %f\n", shadingRate);
-
- oldFrameNumber = [self frameNumber];
- startI = [self startFrame];
- endI = [self endFrame];
- incI = [self frameIncrement];
-
- // due to a bug in NeXT's 3DKit, we want to make sure that
- // nothing gets written out to a view while we're in
- // "copyRIBCode:". Unfortunately, that's pretty hard... The most likely
- // culprit is a routine (like the current camera's interpolation routine)
- // writing out to the "statusText" outlet. Probably the best thing to do
- // then is to save the value of that outlet and set it to nil for the
- // duration of copyRIBCode:... actually, the better thing to do is
- // probably reimplement copyRIBCode:, where I unset the outlet, call
- // the super's version, and then set it back. Yea, let's try that...
-
- shooting = YES;
- [self setFrameNumber:(startI - 1)]; // just to flush state...
- for (i = startI; i < endI; i += incI)
- { [self setFrameNumber:i];
- NXPrintf(ts, "Display \"%s.%d.tiff\" \"file\" \"rgba\"\n", filename, i);
- [self copyRIBCode:ts];
- }
- NXSaveToFile(ts, [savePanel filename]);
- NXCloseMemory(ts,NX_FREEBUFFER);
-
- [self setFrameNumber:oldFrameNumber];
- shooting = NO;
- }
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "done writing RIB!");
- [statusText setStringValue:statusBuf];
- }
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "building scene visualizing shot...");
- [statusText setStringValue:statusBuf];
- }
-
- // first determine how long the shot is:
- theShotDuration = ([self endFrame] - [self startFrame]) * [self frameIncrement];
-
- // now open a stream to write the eve file out to
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- NXPrintf(ts, "# This eve scene file visualizes the shot %s\n", [savePanel filename]);
-
- return self;
- }
-
-
- - dumpEve:sender
- {
- static id savePanel=nil;
- NXStream *ts;
-
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "dumping Eve...");
- [statusText setStringValue:statusBuf];
- }
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- [savePanel setRequiredFileType:"eve"];
- }
-
- if([savePanel runModal])
- { // returned w/pathname, open a stream and
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- // feed to NXPrintf to put in the custom Display command
- NXPrintf(ts, "# This eve model file generated by Michael B. Johnson's WW3DKit software running under NeXTSTEP.\n");
- NXPrintf(ts, "# Contact him at wave@media.mit.edu or (617) 547-0563 for more information.\n#\n");
-
- [[worldShape tclInterp] writeState:ts];
-
- // then tell the worldShape to write itself out, which will recurse down...
- [worldShape writeEve:ts atTabLevel:0];
-
- // save the stream to the file selected in the savepanel
- NXSaveToFile(ts, [savePanel filename]);
-
- // and close the stream (which also flushes it), also making sure
- // that the allocated memory is freed.
- NXCloseMemory(ts,NX_FREEBUFFER);
- }
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "done!");
- [statusText setStringValue:statusBuf];
- }
- return self;
- }
-
-
- - dumpScene:sender
- {
- static id savePanel=nil;
- NXStream *ts;
-
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "dumping scene...");
- [statusText setStringValue:statusBuf];
- }
-
- if (!savePanel)
- { savePanel=[SavePanel new];
- [savePanel setRequiredFileType:"eve"];
- }
-
- if([savePanel runModal])
- { // returned w/pathname, open a stream and
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- NXPrintf(ts, "#\n");
- NXPrintf(ts, "# This eve scene file generated by Michael B. Johnson's WW3DKit software running under NeXTSTEP.\n");
- NXPrintf(ts, "# Contact him at wave@media.mit.edu or (617) 547-0563 for more information.\n#\n");
-
- [[worldShape tclInterp] writeState:ts];
-
- // then tell the worldShape to write itself out, which will recurse down...
- [worldShape writeScene:ts atTabLevel:0];
-
- // save the stream to the file selected in the savepanel
- NXSaveToFile(ts, [savePanel filename]);
-
- // and close the stream (which also flushes it), also making sure
- // that the allocated memory is freed.
- NXCloseMemory(ts,NX_FREEBUFFER);
- }
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "done!");
- [statusText setStringValue:statusBuf];
- }
- return self;
- }
-
-
- - turnOffCropWindow
- {
- selectionRegion.size.width = 0.0;
- selectionRegion.size.height = 0.0;
- return self;
- }
-
- - dumpRIBToFile:(char *)filename usingShadingRate:(float)sRate hider:(char *)hiderName pixelSamples:(float)pixelSampleX :(float)pixelSampleY
- {
- NXStream *ts;
- NXRect myFrame;
- char buf[MAXPATHLEN+1];
- float cropMinX, cropMinY, cropMaxX, cropMaxY;
-
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "dumping RIB to file %s...", filename);
- [statusText setStringValue:statusBuf];
- }
-
- ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
-
- // process the file name for a custom display line such that
- // "prman <<filename>>.rib" will put the resulting image somewhere
- // predictably useful.
- strcpy(buf, filename);
-
- // remove the .rib extension from the path returned by the SavePanel
- strrchr(buf,'.')[0]='\0';
-
- // feed to NXPrintf to put in the custom Display command
- NXPrintf(ts, "# This RIB file generated by Michael B. Johnson's WW3DKit software running under NeXTSTEP.\n");
- NXPrintf(ts, "# Contact him at wave@media.mit.edu or (617) 547-0563 for more information.\n#\n");
- NXPrintf(ts, "Display \"%s.tiff\" \"file\" \"rgba\"\n", buf);
- NXPrintf(ts, "ShadingRate %f\n", sRate);
- NXPrintf(ts, "Hider \"%s\"\n", hiderName);
- NXPrintf(ts, "PixelSamples %f %f\n", pixelSampleX, pixelSampleY);
- [self getFrame:&myFrame];
-
- if ((selectionRegion.size.width > selectionWidthEpsilon)||(selectionRegion.size.height > selectionHeightEpsilon))
- { NXLogError("\n\nselectionRegion.origin == (%f, %f)\t\tselectionRegion.size == (%f, %f)\n",
- selectionRegion.origin.x, selectionRegion.origin.y,
- selectionRegion.size.width, selectionRegion.size.height);
- NXLogError("myFrame.origin == (%f, %f)\t\tmyFrame.size == (%f, %f)\n",
- myFrame.origin.x, myFrame.origin.y,
- myFrame.size.width, myFrame.size.height);
- //////// X //////////
- if (selectionRegion.origin.x < 0.0)
- { cropMinX = 0.0;
- }
- else
- { cropMinX = selectionRegion.origin.x/myFrame.size.width;
- }
-
- if ((selectionRegion.size.width + selectionRegion.origin.x) > myFrame.size.width)
- { cropMaxX = 1.0;
- }
- else
- { cropMaxX = (selectionRegion.size.width + selectionRegion.origin.x)/myFrame.size.width;
- }
-
- //////// Y (note Y is flipped) //////////
- if (selectionRegion.origin.y < 0.0)
- { cropMaxY = 1.0;
- }
- else
- { cropMaxY = 1.0 - (selectionRegion.origin.y/myFrame.size.width);
- }
-
- if ((selectionRegion.size.height + selectionRegion.origin.y) > myFrame.size.height)
- { cropMinY = 0.0;
- }
- else
- { cropMinY = 1.0 - ((selectionRegion.size.height + selectionRegion.origin.y)/myFrame.size.height);
- }
-
- NXLogError("CropWindow %f %f %f %f\n", cropMinX, cropMaxX, cropMinY, cropMaxY);
-
- if (cropMinX < 0.0) { cropMinX = 0.0; }
- if (cropMinY < 0.0) { cropMinY = 0.0; }
- if (cropMaxX > 1.0) { cropMaxX = 1.0; }
- if (cropMaxY > 1.0) { cropMaxY = 1.0; }
-
- NXPrintf(ts, "CropWindow %f %f %f %f\n", cropMinX, cropMaxX, cropMinY, cropMaxY);
- }
- // then feed the rib code to the stream and
- [self copyRIBCode:ts];
- // save the stream to the file selected in the savepanel
- NXSaveToFile(ts, filename);
-
- // and close the stream (which also flushes it), also making sure
- // that the allocated memory is freed.
- NXCloseMemory(ts,NX_FREEBUFFER);
-
- if (statusText) // potentially record activity
- { sprintf(statusBuf, "done!");
- [statusText setStringValue:statusBuf];
- }
- return self;
- }
-
-
- - dumpRIBToFile:(char *)filename { return [self dumpRIBToFile:filename usingShadingRate:shadingRate hider:"hidden" pixelSamples:2 :2]; }
-
-
- // when the well gets resized, I have to catch this and tell
- // theRotator about it, cause the default doesn't seem to do it (cause it
- // ain't a subview, natch)...
- - sizeTo:(NXCoord)deltaWidth :(NXCoord)deltaHeight
- {
- NXPoint aPoint;
- float radius;
-
-
- [super sizeTo:deltaWidth :deltaHeight];
-
- if (deltaWidth > deltaHeight)
- { radius = deltaHeight / 2.0;
- }
- else
- { radius = deltaWidth / 2.0;
- }
- aPoint.x = deltaWidth/2.0;
- aPoint.y = deltaHeight/2.0;
-
- [theRotator setCenter:&aPoint andRadius:radius];
-
- return self;
- }
-
- - setImageFile:(const char *)filename
- {
- // It's actually a bad idea to free this image, because it might be shared...
- // in this case, screw it, cause this has a very specific use...
- if (filename && *filename)
- { image = [NXImage findImageNamed:filename];
- if (!image)
- { image = [[NXImage alloc] init];
- [image setDataRetained:YES];
- if (![image loadFromFile:filename])
- { [self setImage:nil];
- NXLogError("unable to load image from file <%s>\n", filename);
- return nil;
- }
- }
- }
- else
- { [self setImage:nil];
- return nil;
- }
-
- return self;
- }
-
- - setImage:i
- { //if (image)
- //{ [image free];
- //}
- image = i;
- return self;
- }
-
- #define SIZE 1
- static float pattern[SIZE] = {2.};
- static float offset = 0;
-
- - drawPS:(NXRect *)rects :(int)nRects
- {
- NXPoint p = {0.0, 0.0};
- NXSize s;
-
- if ((selectionRegion.size.width > selectionWidthEpsilon)||(selectionRegion.size.height > selectionHeightEpsilon))
- { PSsetgray(NX_WHITE);
- PSsetlinewidth(0.0);
- PSsetdash(pattern,SIZE, offset);
- PSrectstroke(selectionRegion.origin.x, selectionRegion.origin.y,
- selectionRegion.size.width, selectionRegion.size.height);
-
- p.x = ((selectionRegion.origin.x) > 0) ? (selectionRegion.origin.x):0;
- p.y = ((selectionRegion.origin.y) > 0) ? (selectionRegion.origin.y):0;
- }
-
- // there is a bug in 3.2 HP that gets tickled when you have a View
- // that is 32 bits deep and has qrman drawing into it. Since I don't
- // *really* use the fact that there is an alpha component to this image
- // when I composite it in here, I'm going to punt on doing a "source over"
- // operation, and just copy it into the View.
-
- if (image)
- { //NXSetColor(NX_COLORBLACK);
- //PSsetalpha(1.0);
- [image getSize:&s];
- PScompositerect(p.x, p.y, s.width, s.height, NX_COPY); // used to be PScompositerect(p.x, p.y, s.width, s.height, NX_SOVER);
- [image composite:NX_COPY toPoint:&p]; //used to be [image composite:NX_SOVER toPoint:&p];
- }
- return self;
- }
-
-
- // need to add timed entries if I'm still holding the modifier down
- // when I exit the inner modal loop. Use the velocity at exit to set the
- // frequency of the timed entry...
- // When I reenter the mouseDown loop, I should remove any outstanding timed entries.
- // when doing a timed entry, I should record frame rate and display it on the status bar
-
- - removeAnimateTE
- {
- if (animateTE)
- { DPSRemoveTimedEntry(animateTE);
- animateTE = 0;
- animateRotate = NO;
- // switch back to the N3D_SmoothSolids surface type
- [self setSurfaceTypeForAll:renderStyle chooseHider:YES];
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, tesselationVector, RI_NULL);
- }
- return self;
- }
-
-
- - animateRotate
- {
- [theRotator trackMouseFrom:&oldMouse to:&newMouse rotationMatrix:rmat andInverse:irmat];
- [worldShape concatTransformMatrix:rmat premultiply:YES];
- oldMouse.x = newMouse.x;
- oldMouse.y = newMouse.y;
- newMouse.x += dMouse.x;
- newMouse.y += dMouse.y;
- // NXLogError("old == (%f, %f) new == (%f, %f)\n", oldMouse.x, oldMouse.y, newMouse.x, newMouse.y);
- return self;
- }
-
-
- - animateScale
- {
- return self;
- }
-
-
- - animateTranslate
- {
- return self;
- }
-
-
- - animateClick
- {
- if (animateRotate) { [self animateRotate]; }
- if (animateScale) { [self animateScale]; }
- if (animateTranslate) { [self animateTranslate]; }
- [self display];
- return self;
- }
-
-
- void animateHandler(DPSTimedEntry teNumber, double now, void *userData)
- {
- id myObj = (id)userData;
-
- [myObj animateClick];
- return ;
- }
-
-
- - removeRenderTE
- {
- if (renderTE)
- { DPSRemoveTimedEntry(renderTE);
- renderTE = 0;
- renderCount = 0;
- backgroundRendering = NO;
- }
- return self;
- }
-
-
- - setBackgroundRenderingOff { [self removeRenderTE]; return self; }
-
- - (BOOL)backgroundRendering { return backgroundRendering; }
-
- - backgroundRender
- {
- if (!backgroundRendering)
- { renderCount++;
- if (renderCount == renderAtMediumRate)
- { NXLogError("starting medium render...\n");
- backgroundRendering = YES;
- [delegate setRenderStartTime];
- [self renderAsTIFF];
- }
- if (renderCount == renderAtHighRate)
- { NXLogError("starting high render...\n");
- backgroundRendering = YES;
- [delegate setRenderStartTime];
- [self renderAsTIFF];
- }
- }
- return self;
- }
-
-
- void renderHandler(DPSTimedEntry teNumber, double now, void *userData)
- {
- id myObj = (id)userData;
-
- [myObj backgroundRender];
- return ;
- }
-
-
- ////////////////////////////////////////////////////////////////////
- // So user can get some feedback
- ///////////////////////////////////////////////////////////////////
-
- static void getRegion(NXRect *region, const NXPoint *p1, const NXPoint *p2)
- /*
- * Returns the rectangle which has p1 and p2 as its corners.
- */
- {
- region->size.width = p1->x - p2->x;
- region->size.height = p1->y - p2->y;
- if (region->size.width < 0.0) {
- region->origin.x = p2->x + region->size.width;
- region->size.width = ABS(region->size.width);
- } else {
- region->origin.x = p2->x;
- }
- if (region->size.height < 0.0) {
- region->origin.y = p2->y + region->size.height;
- region->size.height = ABS(region->size.height);
- } else {
- region->origin.y = p2->y;
- }
- }
-
-
- #define ACTIVEBUTTONMASK (NX_MOUSEUPMASK|NX_MOUSEDRAGGEDMASK|NX_ALTERNATEMASK|NX_CONTROLMASK|NX_COMMANDMASK)
- - mouseDown:(NXEvent *)theEvent
- {
- int oldMask;
- //NXPoint p, last, start;
- //NXRect visibleRect, oldRegion;
- NXPoint start;
- RtPoint myEyePoint,
- previousEyePoint, previousViewPoint;
- float previousRoll;
-
-
- [self removeAnimateTE];
- [self removeRenderTE];
- if (image)
- { [image free];
- image = nil;
- }
-
- dMouse.x = 0.0;
- dMouse.y = 0.0;
-
- // track the mouse until a mouseUp event occurs, updating the display
- // as tracking happens.
- [self lockFocus];
- oldMask = [window addToEventMask:ACTIVEBUTTONMASK];
-
- // switch to the N3D_WireFrame surface type
- [self setSurfaceTypeForAll:movingRenderStyle chooseHider:YES];
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, lowRezTesselationVector, RI_NULL);
-
- oldMouse = theEvent->location;
- [self convertPoint:&oldMouse fromView:nil];
- start = oldMouse;
-
- // when the alt key is depressed, we scale the worldShape up or down, depending on mouse movement.
- // otherwise, we rotate the worldShape using the virtual trackball
-
- while (1)
- { newMouse = theEvent->location;
- [self convertPoint:&newMouse fromView:nil];
- dMouse.x = newMouse.x - oldMouse.x;
- dMouse.y = newMouse.y - oldMouse.y;
- if (dMouse.x != 0.0 || dMouse.y != 0.0)
- { if (theEvent->flags & NX_ALTERNATEMASK)
- { switch (trackballAffects)
- { case WW_TRACKBALL_WORLD_SHAPE:
- sprintf(statusBuf, "translating world in Z by %f", (translateZFactor * dMouse.y));
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [worldShape translate:0.0 :0.0 :(translateZFactor * dMouse.y)];
- break;
- case WW_TRACKBALL_CURRENT_SHAPE:
- sprintf(statusBuf, "translating %s in Z by %f", [currentShape shapeName], (translateZFactor * dMouse.y));
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [currentShape translate:0.0 :0.0 :(translateZFactor * dMouse.y)];
- break;
- case WW_TRACKBALL_CAMERA:
- // need to change Eye point
- sprintf(statusBuf, "moving eye point in Z by %f", (translateZFactor * dMouse.y));
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [self moveEyeBy:0.0 :0.0 :(-1. * (translateZFactor * dMouse.y))];
- break;
- }
- }
- else
- { if (theEvent->flags & NX_CONTROLMASK)
- { // NOTE draw rubber band selection here
- getRegion(&selectionRegion, &newMouse, &start);
- [statusText setStringValue:"selecting crop region for rendering..."]; [statusText display]; NXPing();
- //NXInsetRect(&oldRegion, -1.0, -1.0);
- //oldRegion = selectionRegion;
- // last = p;
- }
- else
- { if (theEvent->flags & NX_COMMANDMASK)
- { switch (trackballAffects)
- { case WW_TRACKBALL_WORLD_SHAPE:
- sprintf(statusBuf, "translating world in X & Y by (%f, %f)", (translateXFactor * dMouse.x), (translateYFactor * dMouse.y));
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [worldShape translate:(translateXFactor * dMouse.x)
- :(translateYFactor * dMouse.y) :0.0];
- break;
- case WW_TRACKBALL_CURRENT_SHAPE:
- sprintf(statusBuf, "translating %s in X & Y by (%f, %f)",
- [currentShape shapeName], (translateXFactor * dMouse.x), (translateYFactor * dMouse.y));
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [currentShape translate:(translateXFactor * dMouse.x)
- :(translateYFactor * dMouse.y) :0.0];
- break;
- case WW_TRACKBALL_CAMERA:
- sprintf(statusBuf, "moving eye in X & Y by (%f, %f)", (translateXFactor * dMouse.x), (translateYFactor * dMouse.y));
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [self moveEyeBy:(-1. * (translateXFactor * dMouse.x))
- :(-1. * (translateYFactor * dMouse.y)) :0.0];
- break;
- }
- }
- else
- { [theRotator trackMouseFrom:&oldMouse to:&newMouse rotationMatrix:rmat andInverse:irmat];
- switch (trackballAffects)
- { case WW_TRACKBALL_WORLD_SHAPE:
- sprintf(statusBuf, "rotating world...");
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [worldShape concatTransformMatrix:rmat premultiply:YES];
- break;
- case WW_TRACKBALL_CAMERA:
- sprintf(statusBuf, "rotating camera...");
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [self getEyeAt:&previousEyePoint toward:&previousViewPoint roll:&previousRoll];
- myEyePoint[0] = previousEyePoint[0] + (-1. * (translateXFactor * dMouse.x));
- myEyePoint[1] = previousEyePoint[1] + (-1. * (translateYFactor * dMouse.y));
- myEyePoint[2] = previousEyePoint[2];
- [self setEyeAt:myEyePoint toward:previousViewPoint roll:previousRoll];
- break;
- case WW_TRACKBALL_CURRENT_SHAPE:
- sprintf(statusBuf, "rotating %s...", [currentShape shapeName]);
- [statusText setStringValue:statusBuf]; [statusText display]; NXPing();
- [currentShape concatTransformMatrix:rmat premultiply:YES];
- break;
- }
- }
- }
- }
- [self display];
- NXPing();
- }
- theEvent = [NXApp getNextEvent:ACTIVEBUTTONMASK];
- if (theEvent->type == NX_MOUSEUP)
- { break;
- }
- else
- { oldMouse = newMouse;
- }
- }
- [statusText setStringValue:"done"]; [statusText display]; NXPing();
-
- // check to see if we should go off and render (need a minimum image size, like 16x16)...
-
- // check to see if we should keep rotating or scaling...
- // if mouse was moving significantly, keep going...
- if (((float)fabs((double)(dMouse.x)) > epsilon) || ((float)fabs((double)dMouse.y) > epsilon))
- { // comment out for now...
- //animateTE = DPSAddTimedEntry(.002, (DPSTimedEntryProc)animateHandler, self, NX_BASETHRESHOLD);
- //animateRotate = YES;
- [self setSurfaceTypeForAll:renderStyle chooseHider:YES];
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, tesselationVector, RI_NULL);
- }
- else
- { animateTE = 0;
- animateRotate = NO;
- // switch back to the N3D_SmoothSolids surface type
- [self setSurfaceTypeForAll:renderStyle chooseHider:YES];
- RiGeometricApproximation(RI_TESSELATION, RI_PARAMETRIC, tesselationVector, RI_NULL);
-
- //renderTE = DPSAddTimedEntry(renderCheckTimeSlice, (DPSTimedEntryProc)renderHandler, self, NX_BASETHRESHOLD);
- }
-
- [self display];
- [self unlockFocus];
- [window setEventMask:oldMask];
- [window flushWindow];
-
- return self;
- }
-
- - (BOOL)acceptsFirstResponder { return YES; }
-
- - (BOOL)acceptsFirstMouse { return YES; }
-
- - keyDown:(NXEvent *)theEvent
- {
- // id theCmd = nil;
-
-
- // what we want to be able to do is have a set of mappings from the
- // charCode to some piece of tcl code.
- // We also want to be able to have the tcl code be executed in either
- // the camera's interp or the shape interp...
- // we'll say that if the cmd key is held down, it goes to the camera,
- // otherwise we send it to the root shape's interp.
-
- // we should probably have a hash table which has two things:
- // the charCode and the tcl code that corresponds to it
- // if there isn't an entry, drop through...
-
- // if (theEvent->flags & NX_COMMANDMASK) // the command key is being held down : camera!
- // { theCmd = [self cameraCmdFromCharCode:theEvent->data.key.charCode];
- // if (theCmd)
- // { [tclInterp globalEval:[theCmd str]];
- // }
- // [delegate controlsWereUpdated:self];
- // return self;
- // }
- // else // must want to talk to the model, I guess...
- // { theCmd = [self modelCmdFromCharCode:theEvent->data.key.charCode];
- // if (theCmd)
- // { [[rootShape tclInterp] globalEval:[theCmd str]];
- // }
- // [delegate controlsWereUpdated:self];
- // return self;
- // }
-
- return [super keyDown:theEvent];
- }
-
- - takeRenderWorldAsBox:sender { [worldShape setDrawAsBox:[sender intValue]]; return [self display]; }
- - takeRenderCurrentAsBox:sender { [currentShape setDrawAsBox:[sender intValue]]; return [self display]; }
- - takeWorldIsVisible:sender { [worldShape setVisible:[sender intValue]]; return [self display]; }
- - takeCurrentIsVisible:sender { [currentShape setVisible:[sender intValue]]; return [self display]; }
-
- - (BOOL)renderWorldAsBox { return [worldShape doesDrawAsBox]; }
- - (BOOL)renderCurrentAsBox { return [currentShape doesDrawAsBox]; }
- - (BOOL)worldIsVisible { return [worldShape isVisible]; }
- - (BOOL)currentIsVisible { return [currentShape isVisible]; }
-
- - (int)trackballAffects { return trackballAffects; }
- - takeTrackballAffectsFromMatrix:sender
- {
- int newVal = [[sender selectedCell] tag];
-
-
- switch (newVal)
- { case WW_TRACKBALL_WORLD_SHAPE:
- trackballAffects = newVal;
- [self setUsePreTransformMatrix:NO];
- break;
- case WW_TRACKBALL_CAMERA:
- // we assume that [self usesPreTransformMatrix] returns YES...
- trackballAffects = newVal;
- [self setUsePreTransformMatrix:YES];
- break;
- case WW_TRACKBALL_CURRENT_SHAPE:
- trackballAffects = newVal;
- [self setUsePreTransformMatrix:NO];
- break;
- default:
- NXLogError("%d is an invalid value for trackballAffects.\n", newVal);
- }
-
-
- return self;
- }
-
- - (int)trackballXYZ
- {
- N3DAxis theAxis = [theRotator rotationAxis];
- int theAxisInt = -1;
-
-
- if (theAxis == N3D_AllAxes) { theAxisInt = 0; }
-
- if (theAxis == N3D_XAxis) { theAxisInt = 1; }
- if (theAxis == N3D_YAxis) { theAxisInt = 2; }
- if (theAxis == N3D_ZAxis) { theAxisInt = 3; }
-
- if (theAxis == N3D_XYAxes) { theAxisInt = 4; }
- if (theAxis == N3D_XZAxes) { theAxisInt = 5; }
- if (theAxis == N3D_YZAxes) { theAxisInt = 6; }
-
- return theAxisInt;
- }
-
- - takeTrackballXYZFromMatrix:sender
- {
- int newVal = [[sender selectedCell] tag];
-
- switch (newVal)
- { case 0:
- [theRotator setRotationAxis:N3D_AllAxes];
- break;
- case 1:
- [theRotator setRotationAxis:N3D_XAxis];
- break;
- case 2:
- [theRotator setRotationAxis:N3D_YAxis];
- break;
- case 3:
- [theRotator setRotationAxis:N3D_ZAxis];
- break;
- case 4:
- [theRotator setRotationAxis:N3D_XYAxes];
- break;
- case 5:
- [theRotator setRotationAxis:N3D_XZAxes];
- break;
- case 6:
- [theRotator setRotationAxis:N3D_YZAxes];
- break;
- default:
- NXLogError("%d is an invalid value for trackballXYZ.\n", newVal);
- }
- return self;
- }
-
-
- - tclInterp { return tclInterp; }
-
-
- /// new camera stuff
- - takeFocalLength:sender { return [self setFocalLength:[sender floatValue]]; }
- - takeFocalDistance:sender { return [self setFocalDistance:[sender floatValue]]; }
- - takeFStop:sender { return [self setFStop:[sender floatValue]]; }
- - takeExposureLength:sender { return [self setExposureLength:[sender floatValue]]; }
-
- - takeShotOutputTypeFromMatrix:sender
- { NXLogError("[WW3DCamera takeShotOutputTypeFromMatrix:sender] is not really implemented yet.\n");
- shotOutputType = [[sender selectedCell] tag];
- return self;
- }
-
- - takeShotLength:sender { return [self setShotLength:[sender floatValue]]; }
- - takeFramesPerSecond:sender { return [self setFramesPerSecond:[sender floatValue]]; }
- - takeFrameNumber:sender { return [self setFrameNumber:[sender intValue]]; }
-
- - takeExposureLengthFactor:sender { return [self setExposureLengthFactor:[sender floatValue]]; }
- - takeShotStartTime:sender { return [self setShotStartTime:[sender floatValue]]; }
-
-
- - setRenderStyle:(int)s { renderStyle = s; [self setSurfaceTypeForAll:renderStyle chooseHider:YES]; [self display]; return self; }
- - (int)renderStyle { return renderStyle; }
-
- - setMovingRenderStyle:(int)s { movingRenderStyle = s; return self; }
- - (int)movingRenderStyle { return movingRenderStyle; }
-
- - (NXColor) backgroundColor { return backgroundColor; }
- - setBackgroundColor:(NXColor)c { backgroundColor = c; [self display]; return self; }
-
- - (BOOL)showSelectedShape { return showSelectedShape; }
- - setShowSelectedShape:(BOOL)flag
- {
- showSelectedShape = flag;
- [currentShape setSelected:flag andDrawOrigin:drawOriginForSelectedShape];
- [self display];
- return self;
- }
-
- - setSceneClock:newSceneClock { sceneClock = newSceneClock; return self; }
- - sceneClock { return sceneClock; }
-
- - (BOOL)drawOriginForSelectedShape { return drawOriginForSelectedShape; }
- - setDrawOriginForSelectedShape:(BOOL)flag
- {
- drawOriginForSelectedShape = flag;
- [currentShape setDrawOrigin:flag];
- [self display];
- return self;
- }
-
- - otherLightList { return otherLightList; }
-
- - addLocalLight:light usingPath:(const char *)aParentPath
- {
- id theLightParent = [[self worldShape] getChildGivenPath:aParentPath];
-
-
- if (theLightParent)
- { [theLightParent addChild:light];
- [otherLightList addObject:light];
- return self;
- }
- return nil;
- }
-
- - setStatusText:newStatusText { statusText = newStatusText; return self; }
- - statusText { return statusText; }
-
- #define typeVectorVersion1 "i*ffffffff@[2f][2f]fiifcci@cffffffff@@@"
- #define typeValuesVersion1 &renderStyle, &ribName, \
- &scaleUpFactor, &scaleDownFactor, &translateXFactor, &translateYFactor, &translateZFactor, \
- &epsilon, &selectionWidthEpsilon, &selectionHeightEpsilon, \
- &image, &lowRezTesselationVector, &tesselationVector, &shadingRate, \
- &renderAtMediumRate, &renderAtHighRate, &renderCheckTimeSlice, &showSelectedShape, &drawOriginForSelectedShape, \
- &movingRenderStyle, &tclInterp, &defaultLightsInUse, \
- &fStop, &focalLength, &focalDistance, &shutterOpenTime, &exposureLength, &frameTimeIncrement, &shotLength, &framesPerSecond, \
- &ambientLight, &leftLight, &rightLight
-
-
- #define typeVectorVersion2 "i*ffffffff@[2f][2f]fiifcci@cffffffff@@@"
- #define typeValuesVersion2 &renderStyle, &ribName, \
- &scaleUpFactor, &scaleDownFactor, &translateXFactor, &translateYFactor, &translateZFactor, \
- &epsilon, &selectionWidthEpsilon, &selectionHeightEpsilon, \
- &image, &lowRezTesselationVector, &tesselationVector, &shadingRate, \
- &renderAtMediumRate, &renderAtHighRate, &renderCheckTimeSlice, &showSelectedShape, &drawOriginForSelectedShape, \
- &movingRenderStyle, &tclInterp, &defaultLightsInUse, \
- &fStop, &focalLength, &focalDistance, &shutterOpenTime, &exposureLength, &frameTimeIncrement, &shotLength, &framesPerSecond, \
- &ambientLight, &leftLight, &rightLight
-
-
- #define typeVectorVersion3 "i*ffffffff@fiifcci@cffffffff@@@"
- #define typeValuesVersion3 &renderStyle, &ribName, \
- &scaleUpFactor, &scaleDownFactor, &translateXFactor, &translateYFactor, &translateZFactor, \
- &epsilon, &selectionWidthEpsilon, &selectionHeightEpsilon, \
- &image, &shadingRate, \
- &renderAtMediumRate, &renderAtHighRate, &renderCheckTimeSlice, &showSelectedShape, &drawOriginForSelectedShape, \
- &movingRenderStyle, &tclInterp, &defaultLightsInUse, \
- &fStop, &focalLength, &focalDistance, &shutterOpenTime, &exposureLength, &frameTimeIncrement, &shotLength, &framesPerSecond, \
- &ambientLight, &leftLight, &rightLight
-
- #define typeVector "i*ffffffff@fiifcci@cffffffff@@@ff"
- #define typeValues &renderStyle, &ribName, \
- &scaleUpFactor, &scaleDownFactor, &translateXFactor, &translateYFactor, &translateZFactor, \
- &epsilon, &selectionWidthEpsilon, &selectionHeightEpsilon, \
- &image, &shadingRate, \
- &renderAtMediumRate, &renderAtHighRate, &renderCheckTimeSlice, &showSelectedShape, &drawOriginForSelectedShape, \
- &movingRenderStyle, &tclInterp, &defaultLightsInUse, \
- &fStop, &focalLength, &focalDistance, &shutterOpenTime, &exposureLength, &frameTimeIncrement, &shotLength, &framesPerSecond, \
- &ambientLight, &leftLight, &rightLight, &shotStartTime, &exposureLengthFactor
-
-
- - read:(NXTypedStream *)stream
- {
- int version;
-
- [super read:stream];
-
- NX_DURING
- version = NXTypedStreamClassVersion(stream, "WW3DCamera");
- if (version == 0) NXReadTypes(stream,"i",&version), version=1;
- if (version == 1) {
- NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
- backgroundColor = NXReadColor(stream);
- ribColor = NXReadColor(stream);
- shotStartTime = 0.0;
- exposureLengthFactor = 1.0;
- }
- if (version == 2) {
- NXReadTypes(stream, typeVectorVersion2, typeValuesVersion2);
- backgroundColor = NXReadColor(stream);
- ribColor = NXReadColor(stream);
- shotStartTime = 0.0;
- exposureLengthFactor = 1.0;
- }
- if (version == 3) {
- NXReadTypes(stream, typeVectorVersion3, typeValuesVersion3);
- NXReadArray(stream, "f", 2, lowRezTesselationVector);
- NXReadArray(stream, "f", 2, tesselationVector);
- backgroundColor = NXReadColor(stream);
- ribColor = NXReadColor(stream);
- sceneClock = NXReadObject(stream);
- shotStartTime = 0.0;
- exposureLengthFactor = 1.0;
- }
- if (version == 4) {
- NXReadTypes(stream, typeVector, typeValues);
- NXReadArray(stream, "f", 2, lowRezTesselationVector);
- NXReadArray(stream, "f", 2, tesselationVector);
- backgroundColor = NXReadColor(stream);
- ribColor = NXReadColor(stream);
- sceneClock = NXReadObject(stream);
- }
- NX_HANDLER
- NXLogError("in read: %s, exception [%d] raised.\n", [[self class] name], NXLocalHandler.code);
- return nil;
- NX_ENDHANDLER
- return self;
- }
-
- - write:(NXTypedStream *)stream
- {
- [super write:stream];
- exposureLength = savedExposureLength; // just to make sure we archive it...
- NXWriteTypes(stream, typeVector, typeValues);
- NXWriteArray(stream, "f", 2, lowRezTesselationVector);
- NXWriteArray(stream, "f", 2, tesselationVector);
- NXWriteColor(stream, backgroundColor);
- NXWriteColor(stream, ribColor);
- NXWriteObjectReference(stream, sceneClock);
- return self;
- }
-
- @end
-